shuhelohelo’s blog

Xamarin.Forms多めです.

Prismを使ったXamarin.FormsプロジェクトでSqliteを使う

SqliteはDBをファイルとして扱うので,そのdbファイルを保存する必要があるのですが,この保存先はプラットフォームごとに異なります. プラットフォームごとの処理を呼び分けたいときは,以下の記事のとおり,IPlatformInitializerクラスを使う.

blog.okazuki.jp

Prismを適用した場合,例えばAndroidではMainActivity.csに以下のようにIPlatformInitializerを継承したAndroidInitializerクラスがあります.

この中のRegisterTypesメソッドで,DIするオブジェクトをDIコンテナに登録する事ができます.

    public class AndroidInitializer : IPlatformInitializer
    {
        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            // Register any platform specific implementations
            containerRegistry.RegisterSingleton<IPlatformInfoService, PlatformInfoService>();
            containerRegistry.RegisterSingleton<IPlaceRepository, PlaceRepository>();
        }
    }

各プラットフォームの情報を取得するためのクラスを登録しています. このクラスを介してDBファイルの保存先のパスを取得しています.

このプラットフォーム固有の情報を取得するクラスをIPlatformInfoServiceを継承するクラスとして,各プラットフォームのプロジェクト内に作成します.

この例では,プラットフォームごとに異なるDBファイルのパスを返すようにします.

    public class PlatformInfoService : IPlatformInfoService
    {
        private string _dbFileName = "AppDb.db";

        public string GetUserDataFolderPath()
        {
            return Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal));
        }

        public string GetSqliteDbPath()
        {
            return Path.Combine(GetUserDataFolderPath(), _dbFileName);
        }
    }

このクラスはPlaceRepositoryクラス内で,dbContextインスタンスを作成する際にSqliteのDBファイルのパスを取得するために使用されます.

DIコンテナを介してPlaceRepositoryにPlatformInfoServiceをDIしています.

    public class PlaceRepository : IPlaceRepository
    {
        private AppDbContext _dbContext;

        public PlaceRepository(IPlatformInfoService dbpathService)
        {
            this._dbContext = new AppDbContext(dbpathService.GetSqliteDbPath());
        }

        //省略
    }

PrismのDIの仕組みによって,ここまでで共通プロジェクトはRepositoryの実装が漏れずにすんでいる.

共通プロジェクトが知っているのはIPlaceRepositoryインターフェースだけ.

以下のアプリケーションで使用している.

github.com