Anurag
Anurag

Reputation: 378

Implementing Generic Repository and UnitOfWork

I have followed this tutorial.

I got to a stage of calling a repository using _unitOfWork.XYZRepository.Get(), now to take it further I want to write an interface for my UnitOfWork class and inject it to my controller.

I am not sure whether I need write interface for GenericRepository or UnitofWork class or both.

Can some one guide me in this as to what needs to be done to instantiate a repository with interface instead of private readonly UnitOfWork _unitOfWork = new UnitOfWork(); as shown in the link above.

Upvotes: 2

Views: 783

Answers (3)

Anurag
Anurag

Reputation: 378

Based on suggestions I have made following changes...

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

Everything works now... Thanks for the help...

Upvotes: 1

Eric LaForce
Eric LaForce

Reputation: 2151

I have used Autofac for this purpose. In my Global.asax.cs file

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

and then in my controller

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

Essentially leveraging a DI framework and placing the interfaces as parameters to your repositories (or in my case a WebApi controller)

Upvotes: 1

David Osborne
David Osborne

Reputation: 6821

Modify your repository constructor to accept a unit of work, via its interface:

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

Then you instantiate your repository, passing the appropriate unit of work in via the constructor. Alternatively, wire-up your IoC container of choice and let it do the heavy lifting.

Here's a nice tutorial on using Castle Windsor with ASP.NET MVC.

Upvotes: 2

Related Questions