繁体   English   中英

C#/ EF和存储库模式:将ObjectContext放在具有多个存储库的解决方案中的位置?

[英]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限制为单个实例,则可以构建包含ObjectContextRepositoryProvider类,并管理存储库操作到数据提交的传播。 这可以通过以下方式实现: - 将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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM