我在我的项目中使用了UnitOfWork和Repository模式。我正在尝试编写干净的代码。
这是我的工作.cs(应用层(
public interface IUnitOfWork : IDisposable
{
int Save();
IGenericRepository<TEntity> Repository<TEntity>() where TEntity : class;
}
实现工作单元.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())
它就像一个魅力。
现在我有一个自定义存储库ICustomRepository
:
public interface ICustomRepository: IGenericRepository<Entities.Custom>
{
void Test();
}
如何使用IUnitOfWork
访问Test()
功能?
var result = UnitOfWork.Repository<Entities.Custom>().Test(); // not working
更新:
@Thomas 库克给我一种使用演员的方法:
(UnitOfWork.Repository<Entities.Custom>() as ICustomRepository).Test();
我得到一个空引用异常:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
你必须强制转换,因为UnitOfWork
Repository
方法返回一个不声明Test
IGenericRepository
。因此,您需要将返回的值强制转换为继承Test
方法上的IGenericRepository
和螺栓的ICustomRepository
。
虽然强制转换可以工作(如果存储库不为空(,但您可以问自己这是否有用;抽象有什么好处取决于了解它的细节,即:调用者现在知道它实际上是一个non-generic
interface
和type
,即一个ICustomRepository
(顺便说一句,你得到null ref
的原因可能是因为UnitOfWork
只创建generic
存储库,而你的自定义存储库不存在(。
一种更好(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 ...)
{
//
}
只需确保在Unit of Work
中使用与注入存储库的实例相同的DbContext
实例即可。