2013-11-28 3 views
2

나는 this tutorial을 따라갔습니다.일반 저장소 및 UnitOfWork 구현

_unitOfWork.XYZRepository.Get()을 사용하여 리포지토리를 호출하는 단계에 도달했습니다. 이제 더 나아가 내 UnitOfWork 클래스의 인터페이스를 작성하고이를 내 컨트롤러에 삽입하려고합니다.

GenericRepository 또는 UnitofWork 클래스 또는 둘 모두에 쓰기 인터페이스가 필요한지 확실하지 않습니다.

위에서 링크에 표시된대로 private readonly UnitOfWork _unitOfWork = new UnitOfWork(); 대신 인터페이스가있는 저장소를 인스턴스화하기 위해 수행해야 할 작업에 대해 어떤 사람이 나를 안내 할 수 있습니까?

+0

[Ninject] (http://www.ninject.org/)는 매우 인기있는 DI 프레임 워크입니다. –

+0

Ninject에 대해 알고 있지만 GenericRepository/UnitofWork를 컨트롤러에 주입하는 방법을 잘 모르는 경우 IUnitOfWork가 무엇인지 말해 줄 수 있습니까 ??? – Anurag

+0

EF의 DBContext (Repository) ObjectContext (UnitOfWork) –

답변

1

나는이 목적으로 Autofac을 사용했습니다. 내 Global.asax.cs에서

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 컨트롤러에) 내 컨트롤러에 다음

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

및 파일 나는 다음과 같은 변경 한 제안을 바탕으로

2

는 인터페이스를 통해 작업 단위를 받아 들일 저장소 생성자를 수정 :

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

그런 다음 생성자를 통해에서 작업의 적절한 단위를 전달 저장소를 인스턴스화합니다. 또는 IoC 컨테이너를 선택하고 무거운 물건을 들게하십시오.

Here 님께서는 Castle Windsor를 ASP.NET MVC와 함께 사용하는 방법에 대한 훌륭한 자습서를 제공합니다.

+0

데이빗 감사합니다. 제가 따라 한 튜토리얼을보고 앞으로 나아갈 수있는 방법을 알려줄 수 있습니까? 나는 그것을 "Windsor Castle"이라는 패키지를 사용하여 더 복잡하게 만들지 않을 것입니다. – Anurag

+0

이 예에서는 작업 단위 (UOW) 값이 표시되지 않습니다. 이것은 EF 컨텍스트에 대한 추상화 일뿐입니다. 이 방법을 사용하려면 리포지토리를 수정하여 생성자에서 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

위대한, 하나의 답변을 마킹 해 주시겠습니까? (당신이 필요로하는 것에 가장 가깝게 느끼는 것). 다른 사람을 업 투표하는 것도 좋은 기회입니다. –

관련 문제