简体   繁体   中英

How can i use my IUnitOfWork with a BaseController

I am using UnitOfWork and Repository pattern together. I have a base Repository where i handle CRUD operations, and i have <TEntityRepository> for each domain. After all, I am putting all together and using my UnitOfWork.SaveChanges() method to handle those CRUD operations from one pipeline.

Here is my UnitOfWork

    public class UnitOfWork : IUnitOfWork
    {
        private readonly ProductContext _context;

        public UnitOfWork(ProductContext context)
        {
            _context = context;
            Products = new ProductRepository(_context);
            LypProducts = new LypProductRepository(_context);
            CompetitorProducts = new CompetitorProductRepository(_context);
            CompetitorProductLogs = new CompetitorProductLogRepository(_context);
            Competitors = new CompetitorRepository(_context);
            OldProducts = new OldProductRepository(_context);
            Manufacturers = new ManufacturerRepository(_context);
            Categories = new CategoryRepository(_context);
        }

        public ProductRepository Products { get; private set; }
        public LypProductRepository LypProducts { get; private set; }
        public CompetitorProductRepository CompetitorProducts { get; private set; }
        public CompetitorProductLogRepository CompetitorProductLogs { get; private set; }
        public CompetitorRepository Competitors { get; private set; }
        public OldProductRepository OldProducts { get; private set; }
        public ManufacturerRepository Manufacturers { get; private set; }
        public CategoryRepository Categories { get; private set; }

        public int SaveChanges()
        {   
            return _context.SaveChanges();
        }

        public void Dispose()
        {
            _context.Dispose();
        }
    }

Here is my IUnitOfWork

    public interface IUnitOfWork : IDisposable
    {
        ProductRepository Products { get; }
        LypProductRepository LypProducts { get; }
        CompetitorProductRepository CompetitorProducts { get; }
        CompetitorProductLogRepository CompetitorProductLogs { get; }
        CompetitorRepository Competitors { get; }
        OldProductRepository OldProducts { get; }
        ManufacturerRepository Manufacturers { get; }
        CategoryRepository Categories { get; }
        int SaveChanges();
    }

Here is my Repository

    public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        protected readonly DbContext Context;

        public Repository(DbContext context)
        {
            Context = context;
        }

        public TEntity Get(int id)
        {
            return Context.Set<TEntity>().Find(id);
        }

        public async Task<TEntity> GetAsync(int id)
        {
            return await Context.Set<TEntity>().FindAsync(id);
        }
        // Other CRUD operations located here.
   }

Here is my IRepository

        TEntity Get(int id);
        Task<TEntity> GetAsync(int id);
        IEnumerable<TEntity> GetAll();
        Task<IEnumerable<TEntity>> GetAllAsync();
        IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);
        TEntity SingleOrDefault(Expression<Func<TEntity, bool>> predicate);
        void Add(TEntity entity);
        void AddRange(IEnumerable<TEntity> entities);
        void Remove(TEntity entity);
        void RemoveRange(IEnumerable<TEntity> entities);
        void Update(TEntity entity);

i am using this UnitOfWork like this in background jobs without any problem:

            using (var unitOfWork = new UnitOfWork(new ProductContext()))
            {
                var products = unitOfWork.Products.GetAll();
                var oldProducts = unitOfWork.OldProducts.GetAll();
                var manufacturers = unitOfWork.Manufacturers.GetAll();
                var categories = unitOfWork.Categories.GetAll();


                // do stuff

                unitOfWork.SaveChanges();
            }

However, i dont know how to use this logic in WebApi projects. I am frontend engineer, so have no profesional experience on creating WebApis so any help on using this logic in a base controller will appreciated.

From the tags I am assuming you're working with asp.net core project. In this case you can leverage the dependency injection mechanism that comes with it. Basically you register all your repositories and your unit of work in Startup class and inject it into constructors where you need them. The trick for unit of work will be it's lifetime scope. You likely want it to persist between calls while you handle one single request - this is achieved by Scoped lifetime.

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<ProductContext>(o => o.UseInMemoryDatabase("test")); // this is just to prove a point, your EF setup will be different
    // register all your services here
    services.AddScoped<IUnitOfWork, UnitOfWork>(); // Scoped objects are the same within a request, but different across different requests. 
    services.AddTransient<LypProductRepository>(); // and so on and so forth...

    // your other initialisation code here
}

UnitOfWork.cs

public class UnitOfWork : IUnitOfWork
{
    private readonly ProductContext _context;
    public ProductRepository ProductRepository { get; set; }

    public UnitOfWork(ProductContext context, ProductRepository productRepository, ...other repositories) // since you are registering your services in Startup.cs anyway, why not leverage DI here?
    {
        _context = context;
        ProductRepository = productRepository;
        // your other repositories
    }
    ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM