UnitOfWork & Generic Repository,SOLID原则与Custom Repository。

问题描述 投票:5回答:1

我在项目中使用UnitOfWork和Repository模式。我想把代码写得干净点。

这是我的 IUnitOfWork.cs (应用层)

public interface IUnitOfWork : IDisposable
{
    int Save();
    IGenericRepository<TEntity> Repository<TEntity>() where TEntity : class;
}

执行情况 UnitOfWork.cs : (持久层)

public class UnitOfWork : IUnitOfWork
{      
    private readonly DBContext _context;
    private Hashtable _repositories;
    public UnitOfWork(DBContext context)
    {
        _context = context;
    }

    public IGenericRepository<T> Repository<T>() where T : class
    {
        if (_repositories == null)
            _repositories = new Hashtable();

        var type = typeof(T).Name;

        if (!_repositories.ContainsKey(type))
        {
            var repositoryType = typeof(GenericRepository<>);

            var repositoryInstance =
                Activator.CreateInstance(repositoryType
                    .MakeGenericType(typeof(T)), _context);

            _repositories.Add(type, repositoryInstance);
        }

        return (IGenericRepository<T>)_repositories[type];
    }

    public int Save()
    {
        // Save changes with the default options
        return _context.SaveChanges();
    }

    // etc.. Dispose()
}

我的 IGenericRepository.cs : (应用层)

public interface IGenericRepository<TEntity>
    where TEntity : class
{
    void Update(TEntity entity);
    void Delete(object id);
    void InsertList(IEnumerable<TEntity> entities);
    // etc..
}

在我的服务中 。(应用层)

var result = UnitOfWork.Repository<Entities.Example>().Delete(id);

并使用Unity,我在容器中注入依赖关系。

  container.RegisterType<IUnitOfWork, UnitOfWork>(new HierarchicalLifetimeManager())

它的工作就像一个魔法。

现在我有了一个自定义的 Repository ICustomRepository:

public interface ICustomRepository: IGenericRepository<Entities.Custom>
{
    void Test();
}

我怎样才能进入 Test() 用我的 IUnitOfWork?

var result = UnitOfWork.Repository<Entities.Custom>().Test();  // not working

更新:

@Thomas Cook 给我一个使用cast的方法。

   (UnitOfWork.Repository<Entities.Custom>() as ICustomRepository).Test();

我得到一个NullReferenceException。

System.NullReferenceException: 'Object reference not set to an instance of an object.'
c# dependency-injection repository-pattern unit-of-work solid-principles
1个回答
1
投票

你必须要转换,因为 UnitOfWork Repository 方法返回一个 IGenericRepository 没有声明 Test. 因此,你需要将返回的值转为一个叫做 ICustomRepository 继承 IGenericRepository 和螺栓上的 Test 方法。


0
投票

在铸造时 工作(如果仓库不会是空的),你可以问自己这是有用的;一个抽象的你要依靠知道它的细节有什么好处,即:调用者现在的 知道 其实它是 non-generic interfacetype即a ICustomRepository (顺便说一下,你之所以会得到 null ref 大概是因为 UnitOfWork 只是 创建了 generic 仓库,而你的自定义repo不存在)。)

一个更好的(IMO)和更明确的方式来设计你的 Unit of Work 在...中 generic 的方式,但要列出所有的仓库。

public interface IUnitOfWork : IDisposable
{
    int Save();
    ICustomRepository CustomRepository {get;}
    IGenericRepository<Entities.Example> ExampleRepository {get;}
    // etc...
}

这样你就不需要进行任何铸造 了解其细节。

此外,我建议 的构造者的所有资源库。UnitOfWork 从你 依赖注入 而不要让其责任太大。

public UnitOfWork(DBContext context, ICustomRepository customRepository ...)
    {
       //
    }

只要确保你使用 同例DbContext 在你 Unit of Work 作为注入到你的仓库中的那个。

© www.soinside.com 2019 - 2024. All rights reserved.