Prismを使ったXamarin.FormsプロジェクトでSqliteを使う
SqliteはDBをファイルとして扱うので,そのdbファイルを保存する必要があるのですが,この保存先はプラットフォームごとに異なります.
プラットフォームごとの処理を呼び分けたいときは,以下の記事のとおり,IPlatformInitializer
クラスを使う.
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インターフェースだけ.
以下のアプリケーションで使用している.