2013-11-28 2 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

DBContext (репозиторий) ObjectContext (UnitOfWork) в 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. Чтобы это работало, вам придется изменить Хранилища, чтобы принять 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

Отлично, не могли бы вы отметить правильный ответ? (в зависимости от того, что вам ближе). Упреждать других - отличный способ вернуть тоже. –

Смежные вопросы