UnitOfWork 和通用存储库,具有自定义存储库的 SOLID 原则

Zie*_*bhi 5 c# dependency-injection unit-of-work repository-pattern solid-principles

我在我的项目中使用 UnitOfWork 和 Repository 模式。我正在尝试编码干净。

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

public interface IUnitOfWork : IDisposable
{
    int Save();
    IGenericRepository<TEntity> Repository<TEntity>() where TEntity : class;
}
Run Code Online (Sandbox Code Playgroud)

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()
}
Run Code Online (Sandbox Code Playgroud)

我的IGenericRepository.cs:(应用层)

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

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

var result = UnitOfWork.Repository<Entities.Example>().Delete(id);
Run Code Online (Sandbox Code Playgroud)

使用 Unity,我将依赖项注入到容器中。

  container.RegisterType<IUnitOfWork, UnitOfWork>(new HierarchicalLifetimeManager())
Run Code Online (Sandbox Code Playgroud)

它就像一个魅力。

现在我有一个自定义存储库ICustomRepository

public interface ICustomRepository: IGenericRepository<Entities.Custom>
{
    void Test();
}
Run Code Online (Sandbox Code Playgroud)

如何Test()使用我的IUnitOfWork?

var result = UnitOfWork.Repository<Entities.Custom>().Test();  // not working
Run Code Online (Sandbox Code Playgroud)

更新

@Thomas Cook 给了我一种使用 cast 的方法:

   (UnitOfWork.Repository<Entities.Custom>() as ICustomRepository).Test();
Run Code Online (Sandbox Code Playgroud)

我得到一个 NullReferenceException:

System.NullReferenceException: 'Object reference not set to an instance of an object.'
Run Code Online (Sandbox Code Playgroud)

Tho*_*ook 1

您必须进行强制转换,因为UnitOfWork Repository方法返回一个IGenericRepository未声明的Test。因此,您需要将返回值转换为ICustomRepository继承IGenericRepository并固定在该Test方法上的值。