0

データアクセスに汎用リポジトリパターンを使用するアプリケーションがあります。アプリケーションではいくつかの異なるデータベースを使用する必要があるため、NinjectFactoryExtensionを使用してリポジトリファクトリを実装しました。これにより、さまざまなデータベースのリポジトリをオンデマンドで作成できます。次のように、DBContextをファクトリに渡すだけです。

    private readonly IRepository database1;
    private readonly IRepository database2;

    public MembershipService(IRepositoryFactory repositoryFactory)
    {
        this.database1 = repositoryFactory.CreateRepository(new Context("Database1"));
        this.database2 = repositoryFactory.CreateRepository(new Context("Database2"));
    }

このコードで厄介なのは、コンテキストを作成するために必要な文字列です。上記の例の文字列「Database1」と「Database2」。上記のコードをプロジェクト全体で何度も使用すると、単純なタイプミスで大きな問題が発生するのは簡単すぎます。

どうすればこの状況を改善できますか?コンテキストファクトリを作成する必要がありますか?それでもデータベース名が必要になります。どういうわけか列挙型を使用できますか?私はたくさんのアイデアを投げかけてきましたが、何もぴったり合っていないようです

4

3 に答える 3

1

IRepositoryFactory の派生クラスに DbContext を受け入れるコンストラクターを配置します。

class RepositoryFactory : IRepositoryFactory
{
    DbContext _dbc;
    public RepositoryFactory(DbContext db)
    {
       _dbc = db;
    }

    public IRepository CreateRepository()
    {
        return new Repository(_dbc);
    }
}

次に、その DbContext を Ninject インジェクション バインディングにバインドし、これを他のバインディングと共に配置します。

ninjectKernel.Bind<DbContext>().To<EfDbContext>().InRequestScope();

ここで推測しているだけです。これは、RepositoryFactory のインジェクション バインディングがどのように見えるかです。

ninjectKernel.Bind<IRepositoryFactory<Person>>().To<RepositoryFactory<Person>>();

これら 2 つのバインディングを隣り合わせに作成した場合 (順序は重要ではありません)、Ninject は RepositoryFactory のコンストラクターの DbContext パラメーターに値を注入できます。


ここで 60 行目から 76 行目を見てください: http://code.google.com/p/flexigrid-crud-example/source/browse/trunk/FlexigridCrudDemo/FlexigridCrudDemo/NinjectDependencyResolver.cs

ここで EF のリポジトリ パターンを参照してください。22 行目: http://code.google.com/p/to-the-efnh-x/source/browse/trunk/ToTheEfnhX/Ienablemuch.ToTheEfnhX.EntityFramework/EfRepository.cs

ここで NHibernate のリポジトリ パターンを参照してください。24 行目: http://code.google.com/p/to-the-efnh-x/source/browse/trunk/ToTheEfnhX/Ienablemuch.ToTheEfnhX.NHibernate/NhRepository.cs

これら 2 つの異なる ORM をリポジトリ パターンでどのように抽象化したか、接続 (Entity Framework の DbContext、NHibernate の Session) の依存性注入は Ninject によって促進されます。

int target = 1; // memory, nhibernate, entity framework

switch (target)
{
    case 0:
        ninjectKernel.Bind<IRepository<Person>>().ToMethod(x =>
        {
            var person = new MemoryRepository<Person>();
            person.Save(new Person { Username = "Hello", Firstname = "Yo", FavoriteNumber = 9 }, null);
            person.Save(new Person { Username= "See", Firstname = "Nice" }, null);

            return person;
        }
        ).InSingletonScope();


        break;

    case 1:
        ninjectKernel.Bind<ISession>().ToMethod(x => ModelsMapper.GetSessionFactory().OpenSession()).InRequestScope();
        ninjectKernel.Bind<Ienablemuch.ToTheEfnhX.IRepository<Person>>().To<Ienablemuch.ToTheEfnhX.NHibernate.NhRepository<Person>>();
        ninjectKernel.Bind<Ienablemuch.ToTheEfnhX.IRepository<Country>>().To<Ienablemuch.ToTheEfnhX.NHibernate.NhRepository<Country>>();


        break;



    case 2:

        ninjectKernel.Bind<DbContext>().To<EfDbContext>().InRequestScope();
        ninjectKernel.Bind<Ienablemuch.ToTheEfnhX.IRepository<Person>>().To<Ienablemuch.ToTheEfnhX.EntityFramework.EfRepository<Person>>();
        ninjectKernel.Bind<Ienablemuch.ToTheEfnhX.IRepository<Country>>().To<Ienablemuch.ToTheEfnhX.EntityFramework.EfRepository<Country>>();

        break;

    default:
        break;
}
于 2012-05-04T03:04:47.213 に答える
0

ジェネリックリポジトリパターンでも同じ問題が発生しました。解決方法は次のとおりです。

http://blog.staticvoid.co.nz/2012/01/multiple-repository-data-contexts-with.html

これにより、名前空間に基づいて特定のタイプのリポジトリを宣言し、さまざまなデータベースから取得できるようになります。

使用法に関しては、あなたはそれから行くことができます

public MembershipService(IRepository<User> userRepository, IRepository<AppRole> roleRepository)

ここで、UserとAppRoleは別々のDBcontextから来ています

于 2012-05-04T03:11:29.697 に答える
0

データベースごとに異なる DbContext タイプがある場合は、2 つのバインディングを作成することでプロセスを簡素化できます。

kernel.Bind< DatabaseDbContext1 >()。ToSelf ().InRequestScope();

kernel.Bind< DatabaseDbContext2 >()。ToSelf ().InRequestScope();

リポジトリ コンストラクターには、両方のタイプを含めます。

パブリック リポジトリ ( DbContext1、DbContext2 )

DBContext コンストラクターに接続文字列名を配置する必要はありません。各接続文字列に、各 DbContext 名と同じ名前を付けるだけです。EntityFramework が残りを処理します。

于 2014-10-02T01:07:58.293 に答える