Ответ 1
В MvvmCross мы решаем это с помощью другого подхода.
Мы хотели воспользоваться собственными портами SQLite, и мы хотели использовать оболочку ORM SQLite-net из https://github.com/praeclarum/sqlite-net/
Поэтому вместо того, чтобы использовать только PCL, мы сделали следующее:
-
построить основной PCL, содержащий набор межплатформенных интерфейсов SQLite-net и базовых классов https://github.com/slodge/MvvmCross/tree/vnext/Cirrious/Plugins/Sqlite/Cirrious.MvvmCross.Plugins.Sqlite
-
построить расширение/реализацию этой DLL-модуля для каждой платформы
-
используйте общий шаблон и библиотеку DI, чтобы как клиенты PCL, так и не-PCL знали, как загружать и создавать эти плагины.
- например. вы можете увидеть некоторые из них в примере SimpleDroidSql в https://github.com/slodge/MvvmCross/tree/vnext/Sample%20-%20SimpleDialogBinding
На уровне кода клиентские приложения могут использовать плагин как:
В библиотеке бизнес-логики (PCL или специфичной для платформы) код может определять объект модели:
public class ListItem
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
public string WhenCreated { get; set; }
}
во время запуска приложение может вызвать:
Cirrious.MvvmCross.Plugins.Sqlite.PluginLoader.Instance.EnsureLoaded();
var factory = this.GetService<ISQLiteConnectionFactory>();
var connection = factory.Create("SimpleList");
connection.CreateTable<ListItem>();
то во время работы код может делать такие вещи, как:
connection.Insert(new ListItem() { Name = TextToAdd, WhenCreated = DateTime.Now.ToString("HH:mm:ss ddd MMM yyyy") });
или
public ListItem this[int index]
{
get { return _connection.Table<ListItem>().OrderBy(_sortOrder).Skip(index).FirstOrDefault(); }
}
В то время как конкретный код пользовательского интерфейса должен ссылаться на расширение для платформы плагина и внедрять эту реализацию конкретной платформы в систему IoC/DI. На Droid это действительно просто (поскольку MonoDroid поддерживает Assembly.Load во время исполнения), но на других платформах это включает в себя немного кода котельной пластины, например:
protected override void AddPluginsLoaders(Cirrious.MvvmCross.Platform.MvxLoaderPluginRegistry loaders)
{
loaders.AddConventionalPlugin<Cirrious.MvvmCross.Plugins.Sqlite.WinRT.Plugin>();
base.AddPluginsLoaders(loaders);
}
Примечания:
-
текущее репо MvvmCross включает только обертки WinRT и MonoDroid SQLite, но другие (WP * и MonoTouch) должны быть легко построены (и я знаю, что другие их создали, но еще не внесли их обратно)
-
текущее репо MvvmCross включает только интерфейсы sync (не async) для WinRT, но опять же я знаю, что люди сказали мне, что они расширили это в своих частных проектах.
-
В настоящее время я пытаюсь вытащить эту плагиновую структуру за пределы MvvmCross, чтобы плагины можно было использовать более широко. Надеюсь ожидать объявления об этом до Xmas.
-
Подробнее о плагинах в MvvmCross см. https://speakerdeck.com/cirrious/mvvmcross-going-portable