作業単位とリポジトリの私の実装がここでの問題の根源かもしれません..しかし、どこでも作業単位の実装を探すと、別のものが表示されるため、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
出番ですか?