实现通用存储库和UnitOfWork

时间:2013-11-28 14:41:39

标签: c# design-patterns repository-pattern

我已关注this tutorial

我进入了使用_unitOfWork.XYZRepository.Get()调用存储库的阶段,现在为了更进一步,我想为我的UnitOfWork类编写一个接口并将其注入我的控制器。

我不确定是否需要GenericRepositoryUnitofWork类或两者的写入界面。

有人可以指导我如何使用接口而不是private readonly UnitOfWork _unitOfWork = new UnitOfWork();来实例化存储库,如上面的链接所示。

3 个答案:

答案 0 :(得分:2)

通过其界面修改您的存储库构造函数以接受一个工作单元:

public MyRepository(IUnitOfWork unitOfWork)
{
    _unitOfWork = unitOfWork;
}

然后,您实例化您的存储库,通过构造函数传递适当的工作单元。或者,将您选择的IoC容器连接起来,让它完成繁重的工作。

Here是使用Castle Windsor和ASP.NET MVC的一个很好的教程。

答案 1 :(得分:1)

我已将Autofac用于此目的。在我的Global.asax.cs文件中

var builder = new ContainerBuilder();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerApiRequest();
builder.RegisterAssemblyTypes(typeof (LocationTypesRepository).Assembly).Where(
                type => type.Name.EndsWith("Repository")).AsImplementedInterfaces();

然后在我的控制器中

public class LocationTypesController : ApiController
{
    private readonly ILocationRepository _locationRepository;
    private readonly IUnitOfWork _unitOfWork;
    private readonly IAuthenticatedUser _user;

    public LocationTypesController(ILocationRepository locationRepository,
                                   IUnitOfWork unitOfWork, 
                                   IAuthenticatedUser user)
    {
        if (locationRepository == null) 
            throw new ArgumentNullException("locationRepository");
        if (unitOfWork == null) 
            throw new ArgumentNullException("unitOfWork");
        if (user == null) 
            throw new ArgumentNullException("user");

        _locationRepository = locationRepository;
        _unitOfWork = unitOfWork;
        _user = user;
    }

    public IEnumerable<LocationType> Get()
    {
        try
        {
            IEnumerable<Location> locations = _locationRepository.GetAllAuthorizedLocations(_user.UserName);
            _unitOfWork.Commit();
            return locations.Select(location => location.LocationType).Distinct().OrderBy(location => location.LocationTypeId);
        }
        catch (Exception)
        {
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest));
        }
    }

基本上利用DI框架并将接口作为参数放置到您的存储库(或者在我的情况下是WebApi控制器)

答案 2 :(得分:1)

根据我在更改后提出的建议......

public interface IGenericRepository<T> where T : class
{
    IQueryable<T> Get();
    IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
    void Insert(T entity);
    void Delete(T entity);
    void Update(T entity);
    void Save();
    T GetByID(Object id);
}

public class GenericRepository<C, T> : IGenericRepository<T>
    where T : class
    where C : EFDbContext, new()
{

    private C _entities = new C();
    public C Context
    {

        get { return _entities; }
        set { _entities = value; }
    }

    public virtual IQueryable<T> Get()
    {

        IQueryable<T> query = _entities.Set<T>();
        return query;
    }

    public virtual T GetByID(object id)
    {
        return Context.Set<T>().Find(id);
    }
}

//NinjectControllerFactory
private void AddBindings()
{
_ninjectKernel.Bind<IGenericRepository<Product>>().To<GenericRepository<EFDbContext, Product>>();
}

//Controller
[Inject]
public IGenericRepository<Product> ProductRepo;
public ProductController(IGenericRepository<Product> ProductRepository )
    {
        ProductRepo= ProductRepository ;
    }


//Inside Action
model.Products = ProductRepo.Get();

现在一切正常......感谢您的帮助...