1

作業単位リポジトリの私の実装がここでの問題の根源かもしれません..しかし、どこでも作業単位の実装を探すと、別のものが表示されるため、Ninjectにはそれを回避する方法があると確信しています.

IRepository<T>そのため、「作業単位」のコンストラクターに の実装を挿入しています。

_kernel.Bind<IRepository<SomeType1>>().To<RepoOfSomeType1>().WhenInjectedInto<IMyUoWFactory>();
_kernel.Bind<IRepository<SomeType2>>().To<RepoOfSomeType2>().WhenInjectedInto<IMyUoWFactory>();
...

シングルトンスコープDataContextでインスタンス化するようにカーネルをセットアップしました。これは、必要なときにいつでもこの DataContextの同じインスタンスを注入していることを意味すると考えました。

_kernel.Bind<DataContext>().ToConstructor(arg => new MyDataContext(arg.Inject<string>()))
                           .InSingletonScope() // pass same instance to all repositories?
                           ("connection", _someConnectionString);

私が見つけている問題は、各リポジトリに独自のインスタンスがあり、さらに作業単位にも独自のインスタンスがあるように見えることです-したがって、トランザクションをコミットしようとすると例外が発生します(クロスコンテキストトランザクションに関するもの) )。

それに加えて、特定の状況では、接続文字列を動的にする必要があります。これにより、ユーザーが選択したデータベースで作業単位が機能できるようになります。したがって、ファクトリが「必要」です。

その結果、リポジトリごとに 1 つの接続と作業単位ごとに 1 つの接続があり、UoW の目的 (つまり、トランザクション データ操作) が無効になり、このすべてのオーバーヘッドが深刻なパフォーマンスの問題を引き起こしていると思います (+/- 200,000 を実行)小さなデータ操作で... 3-4 時間!!)。

これが、作業単位インスタンスの作成方法です。そこにリポジトリの実装を挿入できるようにしたいのですが、ユーザーが要求した接続文字列を引き続き使用できるようにしたいと考えています。

    public MyUoWFactory(IRepository<Type1> type1repo, IRepository<Type2> type2repo,
                        IRepository<Type3> type3repo, IRepository<Type4> type4repo,
                        IRepository<Type5> type5repo, IRepository<Type6> type6repo)
    {
        _type1Repository = type1repo;
        _type2Repository = type2repo;
        _type3Repository = type3repo;
        _type4Repository = type4repo;
        _type5Repository = type5repo;
        _type6Repository = type6repo;
    }

    public IUnitOfWork Create(string userSelectedConnectionString)
    {
        return new MyUoW(new MyDataContext(userSelectedConnectionString),
                        _type1Repository, _type2Repository, _type3Repository,
                        _type4Repository, _type5Repository, _type6Repository);
    }

私が定義したカーネル バインディングを使用すると、これにより、リポジトリの DataContext がカーネルが指示する場所を指し、作成された UoW の DataContext がユーザーが要求した場所を指すようになります。

service locatorに頼らずにこれをやってのけるにはどうすればよいですか? アプリの起動時ではなく、ユーザーがデータベースを選択したに、リポジトリに DataContext を注入する必要があります。ここでNinject.Factory出番ですか?

4

1 に答える 1

0

Argh ..もう一度やりました(時期尚早の絶望で投稿した直後に答えを見つけました)。私が欲しかったのは、実際にリポジトリを作成するための作業単位ファクトリーでした。したがって、答えは非常に簡単です。 を注入する代わりに、インターフェイスを作成し、代わりにそれを注入しました。IRepository<T>IRepositoryFactory<T>

public interface IRepositoryFactory<T> where T : class
{
    IRepository<T> Create(DataContext context);
}

このようにして、ユーザーが選択した接続文字列を取得するMyUoWFactoryCreateのメソッドは、1 つのコンテキストのみを作成し、それをすべてのリポジトリ ファクトリに渡すことができます。

public MyUoWFactory(IRepositoryFactory<Type1> type1repoFactory, IRepositoryFactory<Type2> type2repoFactory,
                    IRepositoryFactory<Type3> type3repoFactory, IRepositoryFactory<Type4> type4repoFactory,
                    IRepositoryFactory<Type5> type5repoFactory, IRepositoryFactory<Type6> type6repoFactory)
{
    _type1RepositoryFactory = type1repoFactory;
    _type2RepositoryFactory = type2repoFactory;
    _type3RepositoryFactory = type3repoFactory;
    _type4RepositoryFactory = type4repoFactory;
    _type5RepositoryFactory = type5repoFactory;
    _type6RepositoryFactory = type6repoFactory;
}

public IUnitOfWork Create(string userSelectedConnectionString)
{
    var context = new MyDataContext(userSelectedConnectionString)
    return new MyUoW(context,
                    _type1RepositoryFactory.Create(context), 
                    _type2RepositoryFactory.Create(context), 
                    _type3RepositoryFactory.Create(context),
                    _type4RepositoryFactory.Create(context), 
                    _type5RepositoryFactory.Create(context), 
                    _type6RepositoryFactory.Create(context));
}
于 2013-05-03T15:00:36.760 に答える