Внедрение службы CRUD в Xamarin Forms

Я пытаюсь экспериментировать с новой для меня платформой, Xamarin Forms. Основываясь на знаниях .Net Core и EF Core, я решил начать с внедрения службы Sqlite ORM (sqlite-net-pcl) в шаблон Xamarin Forms Shell, включенный в Visual Studio 2019. В этом шаблоне уже реализована служба Mock CRUD на основе in- структура данных памяти, поэтому я хотел реализовать свой собственный сервис и внедрить его с помощью DependencyService. Сначала я модифицировал модель данных с нужным атрибутом:

public class Item
{
    [PrimaryKey, AutoIncrement]
    public string Id { get; set; }
    public string Text { get; set; }
    public string Description { get; set; }
}

Далее я внедрил службу CRUD:

public class SqliteDataStore : IDataStore<Item>
{
    private readonly SQLiteConnection _db;

    public SqliteDataStore()
    {
        _db = new SQLiteConnection(Path.Combine(FileSystem.AppDataDirectory, "items.sqlite"));
        _db.CreateTable<Item>();
        if (_db.Table<Item>().Count().Equals(0))
        {
            _db.InsertAll(new List<Item>
            {
                new Item { Id = Guid.NewGuid().ToString(), Text = "First item", Description = "This is the first item description." },
                new Item { Id = Guid.NewGuid().ToString(), Text = "Second item", Description = "This is the second item description." },
                new Item { Id = Guid.NewGuid().ToString(), Text = "Third item", Description = "This is the third item description." }
            }
            );
        }
    }

    public async Task<bool> AddItemAsync(Item item)
    {
        _db.Insert(item);
        return await Task.FromResult(true);
    }

    public async Task<bool> DeleteItem(string id)
    {
        _db.Delete<Item>(id);
        return await Task.FromResult(true);
    }

    public async Task<Item> GetItemAsync(string id)
    {
        return await Task.FromResult(_db.Get<Item>(id));
    }

    public async Task<IEnumerable<Item>> GetItemsAsync(bool forceRefresh = false)
    {
        return await Task.FromResult(_db.Table<Item>().ToList());
    }

    public async Task<bool> UpdateItemAsync(Item item)
    {
        _db.Update(item);
        return await Task.FromResult(true);
    }
}

Затем я изменил внедренную службу в классе приложения:

public App()
{
    InitializeComponent();

    DependencyService.Register<SqliteDataStore>();
    MainPage = new AppShell();
}

Эта реализация правильно работает с EF Core в Xamarin Forms, но EF Core работает очень медленно, поэтому я изменил ORM (sqlite-net-pcl), и он не работает.


person Marek Słowikowski    schedule 30.10.2019    source источник


Ответы (1)


В документе dependency servicee, в нем говорится:

Важно

Регистрация с помощью методов Register должна выполняться в проектах платформы до того, как функции, предоставляемые реализацией платформы, будут вызваны из общего кода.

Итак, я думаю, вы добавили строку DependencyService.Register<SqliteDataStore>(); не в том месте.

Решение:

Например, в iOS это должно быть:

[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
    public override bool FinishedLaunching(UIApplication app, NSDictionary options)
    {
        global::Xamarin.Forms.Forms.Init();
        LoadApplication(new App());

        DependencyService.Register<SqliteDataStore>();

        return base.FinishedLaunching(app, options);
    }
}

В Android:

protected override void OnCreate(Bundle savedInstanceState)
{
    TabLayoutResource = Resource.Layout.Tabbar;
    ToolbarResource = Resource.Layout.Toolbar;

    base.OnCreate(savedInstanceState);

    DependencyService.Register<SqliteDataStore>();


    Xamarin.Essentials.Platform.Init(this, savedInstanceState);
    global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
    LoadApplication(new App());
}

Существуют также документы о о хранении данных в локальном База данных SQLite.NET и Использование SQLite.NET с Android, можете ссылаться.

person Jack Hua    schedule 30.10.2019
comment
Как я уже упоминал, я реализовал это с помощью EF Core, и он работает, но EF Core слишком тяжел для мобильного приложения. Регистрация может выполняться методом или атрибутом. Регистрация атрибутов может использоваться только для регистрации реализации, зависящей от платформы. В документации используется слово CAN. НЕ ДОЛЖЕН. Завтра я почищу свое решение EF Core, опубликую его на github и вставлю сюда ссылку - person Marek Słowikowski; 30.10.2019
comment
@ MarekSłowikowski Да, но я не вижу регистрацию атрибутов, которую вы используете в DependencyService. Позвольте мне попробовать ваш код, и я обновлю вас позже. - person Jack Hua; 30.10.2019
comment
@ MarekSłowikowski Я просто тестирую ваш код, и у меня все работает хорошо. Единственное, что я изменил, это изменил Id на тип int. Я загрузил образец проекта сюда, и вы можете его проверить. Дайте мне знать, если это сработает для вас. - person Jack Hua; 30.10.2019
comment
Спасибо. Кажется, мне не хватило внимания. Смотря на большие вещи, мы не видим деталей. - person Marek Słowikowski; 30.10.2019
comment
Да, с твоей помощью. Спасибо. - person Marek Słowikowski; 31.10.2019
comment
@ MarekSłowikowski Не могли бы вы отметить этот ответ, если он будет вам полезен :)? - person Jack Hua; 31.10.2019