我在项目中使用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.'
你必须要转换,因为 UnitOfWork
Repository
方法返回一个 IGenericRepository
没有声明 Test
. 因此,你需要将返回的值转为一个叫做 ICustomRepository
继承 IGenericRepository
和螺栓上的 Test
方法。
在铸造时 会 工作(如果仓库不会是空的),你可以问自己这是有用的;一个抽象的你要依靠知道它的细节有什么好处,即:调用者现在的 知道 其实它是 non-generic
interface
和 type
即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
作为注入到你的仓库中的那个。