作为一个学习过程,我尝试使用存储库模式实现UoW,并且我有以下设置:
public interface IUnitOfWork : IDisposable
{
MyEntities Context { get; set; }
string GetConnectionString()
void Complete();
}
public abstract class RepositoryBase<TEntity> : IRepository<TEntity> where TEntity : class
{
protected MyEntities context;
protected DbSet<TEntity> dbSet;
protected RepositoryBase(IUnitOfWork unitOfWork)
{
context = unitOfWork.Context;
dbSet = context.Set<TEntity>();
}
}
public class ItemRepository : RepositoryBase<Item>, IItemRepository
{
public ItemRepository(IUnitOfWork unitOfWork)
: base(unitOfWork)
{
}
public Item GetById(int id)
{
// return a item
}
}
要实际使用ItemRespoitory,我正在执行以下操作:
using (var unitOfWork = new UnitOfWork())
{
var ItemRepository = new ItemRepository(unitOfWork);
var item = ItemRepository.GetById(1);
}
工作正常,现在我想用IoC / DI和简单的进样器做到这一点:
var container = new Container();
container.Register<IUnitOfWork, UnitOfWork>();
container.Register<IItemRepository, ItemRepository>();
container.Verify();
DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
但现在我的问题是,因为我正在将ItemRepository注入控制器的构造函数
public MyController(IItemRepository itemRepository)
{
_itemRepository = itemRepository;
}
当我完成存储库后,我应该如何处理工作单元?因为我没有必要 创建一个单元工作并将其包装在using语句中。我这样做了吗?在我的案例中,应用DI与UoW和repo模式的正确方法应该是什么?感谢。
答案 0 :(得分:2)
您需要将数据服务注册为每个请求 - 对于上面的示例,它可以是Per Web Request或Per Web Api Request
在nuget上查找并安装SimpleInjector.Integration.Web,然后更改:
container.Register<IUnitOfWork, UnitOfWork>();
container.Register<IItemRepository, ItemRepository>();
到此(假设MVC):
container.RegisterPerWebRequest<IUnitOfWork, UnitOfWork>();
container.RegisterPerWebRequest<IItemRepository, ItemRepository>();
你已经完成了。
答案 1 :(得分:0)
如果您将工作单元(UoW)与存储库结合使用,更好的方法是设置UoW以将存储库作为属性保存,而不是将Uow注入每个存储库。
示例:
工作单位(界面):
public interface IUnitOfWork
{
void Commit();
IRepository<Store> Stores { get; }
IRepository<Product> Products { get; }
}
存储库(接口):
public interface IRepository<T> where T : class
{
IQueryable<T> GetAll();
T GetById(Guid id);
void Add(T entity);
void Update(T entity);
void Delete(T entity);
void Delete(Guid id);
}
现在你的控制器中你会有:
public class ProductsController: Controller
{
protected IUnitOfWork Uow { get; set; }
public ProductsController(IUnitOfWork uow)
{
if (uow == null)
throw new ArgumentNullException("Unit of Work");
Uow = uow;
}
}
然后像这样设置你的IoC:
public static void RegisterIoc(HttpConfiguration config)
{
var container = new Container();
container.Register<IUnitOfWork, UnitOfWork>();
container.Register<IRepository<Store>, Repository<Store>>();
container.Register<IRepository<Product>, Repository<Product>>();
}
现在,当您需要Product
DbContext
时,您可以访问控制器中注入的单个Uow。另请注意Commit
方法,这意味着您的实施中只有_dbContext.SaveChanges()
次调用。这就是工作单元的全部内容,对DbContext
进行一些更新调用并进入数据库一次。所以,你有一个像setup这样的事务(意思是,如果出现问题在代码中,任何东西都不会在数据库中更新)。
请注意,这不是一个完全有效的示例,但它应该让您了解如何进行设置。如果您需要有关如何使其工作的教程,您可以查看John Papa关于PluralSight的Single Page Application课程(这是该代码所基于的)。但他有一个非常复杂的设置(虽然非常灵活),这可能有点多开始。