2013-11-28 41 views
2

我跟着this tutorial實施通用庫和UnitOfWork

我調用使用_unitOfWork.XYZRepository.Get()一個倉庫的一個階段,現在採取進一步我想寫一個接口,用於我的UnitOfWork類並將其注入到我的控制器。

我不知道我是否需要GenericRepositoryUnitofWork類的寫入接口,或者兩者都需要。

有人可以指導我做什麼來實現存儲庫的接口,而不是private readonly UnitOfWork _unitOfWork = new UnitOfWork();,如上面的鏈接所示。

+0

[Ninject](http://www.ninject.org/)是一個非常流行的DI框架。 –

+0

我知道Ninject,但不知道如何繼續它注入GenericRepository/UnitofWork到我的控制器,你能告訴我什麼是IUnitOfWork? – Anurag

+0

EF –

回答

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

修改你的資料庫的構造函數接受一個工作單元,通過其接口:

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

然後你實例化你的資料庫,通過構造函數傳遞工作的合適的單位英寸或者,選擇接通您的IoC容器,並讓它完成繁重的工作。

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

+0

謝謝大衛,你可以看看我跟着的教程,並告訴我如何前進的想法。我不打算通過使用「溫莎城堡」包來使它更復雜。 – Anurag

+0

在這個例子中我看不到工作單元中的值。這只是對EF上下文的抽象。爲了讓你的工作順利進行,你必須修改Repositories在構造函數中接受UnitOfWork,然後在上下文的方法中提供更多的抽象。我不確定這是否值得。只需讓您的存儲庫依賴於上下文,並使用上下文作爲您的工作單元,無論如何。 –

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(); 

現在一切正常...感謝您的幫助...

+0

太棒了,你會介意標記一個正確的答案嗎? (無論哪個人都覺得最接近你所需要的)。提升他人是回饋的好方法。 –