[英]C#/EF and the Repository Pattern: Where to put the ObjectContext in a solution with multiple repositories?
我的应用程序中有多个存储库。 我应该把ObjectContext放在哪里? 现在,我有一个像ObjectContext ctx;
的引用ObjectContext ctx;
在每个存储库中。 什么是最聪明,最安全的方法?
只有在Repository
方法提交事务时,才能接受具有多个ObjectContext
实例的设计。 否则,提交事务的外部调用可能无法保留您想要的所有内容,因为您将保留对ObjectContext
不同实例的引用。
如果要将ObjectContext
限制为单个实例,则可以构建包含ObjectContext
的RepositoryProvider
类,并管理存储库操作到数据提交的传播。 这可以通过以下方式实现: - 将ObjectContext
引用注入每个存储库,或者 - 将存储库事件订阅到调用ObjectContext
上相应方法的EventHandler
。
以下是我使用的高度可插拔的实现:
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
。 因此,如果工厂集合包含多个可以为给定存储库Type
创建Repository
工厂,则将使用可枚举中的第一个IFilteredRepositoryFactory
对象,并且将忽略任何后续工厂。 另外,如果没有注册工厂,则会抛出异常。
我通常做的是创建一个ObjectContext并将其存储在线程本地存储中(使用NamedThreadDataSlot)并从那里访问ObjectContext。 这确保了ObjectContext在请求中共享,该请求将由一个线程处理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.