(Wall Of Text で申し訳ありません... :) )
概要
Winfor アプリケーションで依存性注入を使用すると、多数のリポジトリ コンテキストが作成されます。私がこれを使用している方法が正しいか間違っているか、または一般的な慣行が何であるかはわかりません。
詳細
過去 6 か月間、私は Unit OfWork パターンとリポジトリ パターンを実装する ASP.NET MVC アプリケーションを作成してきました。これに加えて、私はこれらすべての Web アプリケーションで依存性注入を使用しており、ある程度の成功を収めています。
これは、私のリポジトリを配線する例です。
public EntityFrameworkRepositoryRegistry()
{
For<IUnitOfWork>()
.HybridHttpOrThreadLocalScoped() // Lifecycle of the object.
.Use<SqlServerContext>() // My EF Context.
.Ctor<string>("connectionString").Is("name=SqlServer_EF")
.Ctor<string>("defaultContainerName").Is("Entities");
// Ayende's EFProf application :)
EntityFrameworkProfiler.Initialize();
Scan(x =>
{
x.TheCallingAssembly();
x.ExcludeNamespaceContainingType<Fake.FakeContext>();
x.WithDefaultConventions();
}
);
}
わかりました-うまくいきます。ここで注意すべき主なことは、
- ライフサイクルが Web シナリオの正しいものであると仮定しています。
- コンテキストは、Web サーバーにヒットする REQUEST ごとに 1 回だけ存在します。
キュール。
さて、私の WinForm アプリケーションでは、最初に 1 つの Unit Of Work オブジェクトを作成し (依存性注入はまだありません)、その赤ちゃんをすべてのサービス (そしてリポジトリ) に渡し続けました。
この win アプリケーションでは、解析する必要があるすべてのテキスト ファイルを見つけるために DB にアクセスします。(例: 25 ファイル)。次に、ファイルごとに新しいパーサーを作成し、各行を読み取り、解析されたデータを db テーブルにチャックします。罰金。
問題は、このコンテキストがすべてのパーサー間で共有されていたため、ショップ全体で深刻なエラーが発生していたことです。
それで、いくつかの依存性注入を追加し、上記のレジストリ コードを使用します。同じことです - 重大なエラーがたくさんあります。これは、単一のスレッド -> winform に対して 1 つのコンテキストが再度作成されたためです。
そのため、コンテキストのレジストリを次のように調整しました:-
public EntityFrameworkRepositoryRegistry(bool isForTheWeb)
{
if (isForTheWeb)
{
For<IUnitOfWork>()
.HybridHttpOrThreadLocalScoped()
.Use<SqlServerContext>()
.Ctor<string>("connectionString").Is("name=SqlServer_EF")
.Ctor<string>("defaultContainerName").Is("Entities");
}
else
{
For<IUnitOfWork>()
.Use<SqlServerContext>()
.Ctor<string>("connectionString").Is("name=SqlServer_EF")
.Ctor<string>("defaultContainerName").Is("Entities");
}
EntityFrameworkProfiler.Initialize();
Scan(x =>
{
x.TheCallingAssembly();
x.ExcludeNamespaceContainingType<Fake.FakeContext>();
x.WithDefaultConventions();
});
}
そのため、WinForm アプリケーションの場合、ライフサイクルが設定されなくなりました。これにより、約160程度のコンテキストが作成されたと思います! (しかし、実際にはエラーでもありませんでした)。
したがって、これが正しい方法であるかどうかはわかりません。
したがって、私のアプリでは、実際には 25 の異なるタイマーが作動し、ファイルを .. たとえば .. 10 秒ごとにチェックします。新しいデータがある場合は、それを解析します。それ以外の場合は、10 秒後に戻ってきてください。
解析されるこれらのファイルのそれぞれは、独自のスレッドである必要がありますか? 次に、スレッドごとにコンテキストを作成しますか? (これはWebシナリオに似ていると感じています)。それともこれでいいの?私はそれが多くのコンテキストであることを知っていますが、各コンテキストはデータベースへのライブ接続を意味するものではありません..そして接続プールでは、これは実際には問題になりません.
非常に多くのコンテキストがある理由は、次のコードのためです...(これらは、いくつかのリポジトリクラスの個別のコンストラクターです...)
public SqlServerContext(string, string);
public GameFileRepository (IUnitOfWork);
public LogEntryRepository(IUnitOfWork);
public AlertRepository(IUnitOfWork);
... etc..
メインのサービスについては...
public PunkBusterParser(IUnitOfWork, IGameFileRepositry,
ILogEntryRepository, ILoggingService);
そのため、サービスには UoW が必要で、各リポジトリにも 1 つ必要です。つまり、それぞれに対して新しいものが作成されます。
私はこれを正しく構造化していないと確信しています...
どんな提案でも心から感謝します!