sqlitexamarin.formsdependency-injectionsqlite-net-pcl

Injection of CRUD service in Xamarin Forms


I try to experiment with new platform for me, Xamarin Forms. Based on .Net Core and EF Core knowledge I decided to begin with injecting Sqlite ORM service (sqlite-net-pcl) in Xamarin Forms Shell template included in Visual Studio 2019. In this template there is already implemented Mock CRUD service based on in-memory data structure so I wanted to implement my own service and inject it with DependencyService. At first I have modified data model with needed attribute:

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

Next I implemented CRUD service:

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);
    }
}

Next I changed injected service in App class:

public App()
{
    InitializeComponent();

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

This implementation properly works with EF Core in Xamarin Forms but EF Core is very slow so I changed ORM (sqlite-net-pcl) and it does not work.


Solution

  • In the document of dependency servicee, it says:

    Important

    Registration with the Register methods must be performed in platform projects, before the functionality provided by the platform implementation is invoked from shared code.

    So, I think you have added the line DependencyService.Register<SqliteDataStore>(); at a wrong place.

    Solution:

    For example, in iOS it should be:

    [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);
        }
    }
    

    In 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());
    }
    

    There is also documents about Store Data in a Local SQLite.NET Database and Using SQLite.NET with Android you can refer.