アプリケーションに複数のリポジトリがあります。ObjectContextはどこに置くべきですか?現在、私はObjectContext ctx;すべてのリポジトリのようなリファレンスを持っています。これを実行するための最も賢明で安全な方法は何ですか?
2 に答える
複数のインスタンスを持つ設計は、メソッドがトランザクションをコミットするObjectContext場合にのみ受け入れられます。Repositoryそうしないと、ObjectContext.
を 1 つのインスタンスに制限する場合は、を含むクラスをObjectContext構築し、データ コミットへのリポジトリ アクションの伝播を管理できます。これは、 - 各リポジトリに参照を注入する、または -で適切なメソッドを呼び出すにリポジトリのイベントをサブスクライブする、のいずれかによって最もよく達成できます。RepositoryProviderObjectContextObjectContextEventHandlerObjectContext
以下は、私が使用した非常にプラグ可能な実装です。
リポジトリ プロバイダー インターフェイス
public interface IRepositoryProvider
{
IRepository this[Type repositoryType] { get; }
}
リポジトリ ファクトリ インターフェイス
実装は に依存していIEnumerable<IFilteredRepositoryFactory>ます。
public interface IFilteredRepositoryFactory{
bool CanCreateRepository(Type repositoryType);
IRepository CreateRepository(Type repositoryType, ObjectContext context);
}
したがって、実装は次のようになります。
リポジトリ プロバイダ クラス
public class RepositoryProvider
{
public RepositoryProvider(ObjectContext context, IEnumerable<IFilteredRepositoryFactory> repositoryFactories)
{
_context = context;
_repositoryFactories = repositoryFactories;
}
private readonly ObjectContext _context;
private readonly IEnumerable<IFilteredRepositoryFactory> _repositoryFactories;
private readonly Dictionary<Type, IRepository> _loadedRepositories;
IRepository this[Type repositoryType]
{
get
{
if(_loadedRepositories.ContainsKey(repositoryType))
{
return _loadedRepositories[repositoryType];
}
var repository = GetFactory(repositoryType).CreateRepository(repositoryType, _context);
_loadedRepositories.Add(repositoryType,repository);
return repository;
}
}
IFilteredRepositoryFactory GetFactory(Type repositoryType)
{
//throws an exception if no repository factory is found
return _repositoryFactories.First(x => x.CanCreateRepository(repositoryType));
}
}
Repository新しいは、最初に一致するファクトリ実装によって作成されることに注意してください。そのため、ファクトリのコレクションに、特定のリポジトリ用にを作成できる複数のファクトリが含まれている場合、列挙可能なオブジェクトの最初のオブジェクトが使用され、後続のファクトリは無視されます。また、登録されたファクトリが無い場合は例外がスローされます。RepositoryTypeIFilteredRepositoryFactory
私が通常行うことは、ObjectContext を一度作成し、それを Thread Local Storage (NamedThreadDataSlot を使用) に格納し、そこから ObjectContext にアクセスすることです。これにより、ObjectContext が要求全体で共有され、1 つのスレッドによって処理されることが保証されます。