我的应用程序中有多个存储库。我应该把 ObjectContext 放在哪里?现在,我ObjectContext ctx;
在每个存储库中都有一个参考。解决此问题的最明智和最安全的方法是什么?
2 回答
仅当您的方法提交事务ObjectContext
时,才可以接受具有多个实例的设计。Repository
否则,提交事务的外部调用可能不会保留您想要的所有内容,因为您将持有对不同实例的引用ObjectContext
。
如果要将 限制ObjectContext
为单个实例,则可以构建一个RepositoryProvider
包含 的类ObjectContext
,并管理存储库操作到数据提交的传播。这可以通过以下方式最好地完成: - 将ObjectContext
引用注入每个存储库,或 - 将存储库的事件订阅到EventHandler
调用ObjectContext
.
以下是我使用的一个高度可插拔的实现:
存储库提供程序接口
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
,第一个匹配的工厂实现将创建一个新的。因此,如果工厂集合包含多个可以Repository
为给定存储库创建的工厂,则将使用可枚举中Type
的第一个IFilteredRepositoryFactory
对象,并且将忽略任何后续工厂。另外,如果没有注册工厂,也会抛出异常。
我通常做的是创建一次 ObjectContext 并将其存储在线程本地存储中(使用 NamedThreadDataSlot)并从那里访问 ObjectContext。这确保了 ObjectContext 在请求之间共享,这将由一个线程处理。