2
votes

First sorry if this was asked already but i cannot find an answer for this 'particular case'.

I've a Interface of Unit of Work:

public interface IUnitOfWork
{
    DbContext Context { get; set; }
    void Dispose();
    void Save();
}

And use a Generic Repository class:

public class GenericRepository<TEntity> where TEntity : class
    {

        private DbSet<TEntity> dbSet;

        private IUnitOfWork UnitOfWork { get; set; }
        private DbContext context { get { return UnitOfWork.Context; } }

        public GenericRepository(IUnitOfWork unitOfWork)
        {
            UnitOfWork = unitOfWork;
            this.dbSet = context.Set<TEntity>();
        }

        public virtual IEnumerable<TEntity> Get(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = "")
        {
            IQueryable<TEntity> query = dbSet;

            if (filter != null)
            {
                query = query.Where(filter);
            }

            foreach (var includeProperty in includeProperties.Split
                (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(includeProperty);
            }

            if (orderBy != null)
            {
                return orderBy(query).ToList();
            }
            else
            {
                return query.ToList();
            }
        }

        public virtual TEntity GetByID(object id)
        {
            return dbSet.Find(id);
        }

        public virtual void Insert(TEntity entity)
        {
            dbSet.Add(entity);
        }

        public virtual void Delete(object id)
        {
            TEntity entityToDelete = dbSet.Find(id);
            Delete(entityToDelete);
        }

        public virtual void Delete(TEntity entityToDelete)
        {
            if (context.Entry(entityToDelete).State == EntityState.Detached)
            {
                dbSet.Attach(entityToDelete);
            }
            dbSet.Remove(entityToDelete);
        }

        public virtual void Update(TEntity entityToUpdate)
        {
            dbSet.Attach(entityToUpdate);
            context.Entry(entityToUpdate).State = EntityState.Modified;
        }
    }

I don't want to do my logic in my MVC controler, so I added a businesslayer. My question is, where should I instantiate (and dispote) my IUnitOfWork, in my controler and pass it to my business layer? Example:

 public static class CircleLogic
    {
        public static void DeleteCircle(IUnitOfWork uow, int id)
        {
            try
            {
                var circleRep = new GenericRepository<Circle>(uow);

                var circle = circleRep.GetByID(id);
                 ......
                  circleRep.Delete(id);            

                uow.Save();

            }
            catch (Exception ex)
            {
                throw;
            }
        }
    }

I've seen this but I don't want to instantiate it in my business layer. What is the best approach?

Thanks!

2
Hum, not sure why it would not?Tom
IMO this is perfect case of abstraction bloat. You should rethink your layers and If you really need IUnitOfWork and generic repository if you are already using ORM. programmers.stackexchange.com/questions/164000/…Euphoric
@Tom, You could inject the repository as well, if you had a constructor.Morten
@Morten, thanks, that is one of my solution, create a non static class that would have 2 constructor.. i really don't need it as it s a simple implementaiton but i m trying to implrement stuff i never did just for learning sakeTom
@euphoric, in my case it s totally useless to work with unitofwork as it's a simple website, but i saw on several tutorial, that it's good practice to be able to do TDD (which i won't), but it can be useful to understandTom

2 Answers

3
votes

I see no harm in passing it into your Business Layer like you have suggested. However, if you want to keep your Business Layer completely persistence ignorant I would suggest introducing an IRepository<T> interface and passing that in instead.

In terms of disposing of the objects, I would make both your IUnitOfWork/Repository classes implement IDisposable so you can make use of the using statement e.g.

public ActionResult DeleteCircle(int id)
{
    using (IUnitOfWork uow = new UnitOfWork())
    {
        using (IRepository<Circle> repo = new GenericRepository<Circle>(uow))
        {
            CircleLogic.DeleteCircle(repo, id);
        }
        uow.Save();
    }
}

...

public static class CircleLogic
{
    public static void DeleteCircle(IRepository<Circle> repo, int id)
    {
        var circle = repo.GetById(id);
        ...
        repo.Delete(id);
    }
}
1
votes

Because your concrete UnitOfWork implementation would most likely live in your persistence layer, it'd be sensible to instantiate it in either the persistence layer or 1 layer above in the business layer. Your UI should have no knowledge of what technology you're using to persist your entities/data.