2

So I've run into a bit of a roadblock, albeit a small one. I think I have a leaky abstraction similar to the answer below:

Leaky abstraction?

I'm using the abstract factory pattern to create factories of repositories. This gives me the ability to keep DBContext light-weight and still allow me to call multiple methods in repository before I call SaveChanges(). The advantage of this is I can batch multiple commands before saving it.

using System.Collections.Generic;

namespace RouteMiningBLL
{
    public class ZIPCodeInfoService
    {
        private readonly IRouteMiningRepositoryFactory factoryRepository;

        public ZIPCodeInfoService(IRouteMiningRepositoryFactory factoryRepository)
        {
            this.factoryRepository = factoryRepository;
        }

        public IList<ZIPCodeInfo> GetAllZIPCodeInfo(int zipcode, int radius)
        {
            using (IZIPCodeInfoRepository repo = factoryRepository.CreateZIPCodeInfoRepository())
            {
                List<ZIPCodeInfo> zipCodeInfos = new List<ZIPCodeInfo>();

                // Get all zipcodes within radius of zipcode from site
                ZIPCodePage page = new ZIPCodePage();
                IEnumerable<int> zipCodes = page.GetZIPCodes(zipcode, radius);

                foreach (int foundZipcode in zipCodes)
                {
                    zipCodeInfos.Add(GetZIPCodeInfo(foundZipcode));
                }

                repo.SaveChanges();

                return zipCodeInfos;
            }
        }
    }
}

Above is my current implementation, but it requires IRouteMiningRepositoryFactory to implement IDisposable which obviously is a leak abstraction. What I'm trying to figure out is how to handle this?

Prior to this I just disposed of the DBContext inside the factory. However, this requires me to create a new DBContext with each Repository method call (not a big issue at all), but this then forces me to call dbContext.SaveChanges() at the end of every repository method (therefore, not letting me batch work). I'm stuck on how to handle Leaky abstraction vs Batching.

In either case I will have a leaky abstraction because DBContext needs to be disposed of. It just changes where it happens (BLL vs DAL). Thanks!

keelerjr12
  • 1,693
  • 2
  • 19
  • 35
  • Well, one could argue that the leaky abstraction here is the GC and the .NET memory management itself. `IDisposable` is *per se* a leaky abstraction. Don't fight wars you can't win. – InBetween Mar 29 '18 at 22:56
  • Valid. I guess my question is: where do I put the leaky abstraction? – keelerjr12 Mar 29 '18 at 22:59
  • I'd put it where it least compromises the functionality you want, – InBetween Mar 29 '18 at 23:00
  • 1
    Thank you for this question, I checked my projects and saw that I inject repositories directly to services without factories, so I had to make all my services `IDisposable`, in terms of design I'm in a couple steps behind you :) I'll start thinking about the refactoring now. – scor4er Mar 29 '18 at 23:10
  • In small to mid size projects, you can just use a dbcontext instance itself as a repository. I find resolving a mock dbcontext for testing and the real deal at runtime is sufficient for these. I've worked on one particular project where the original lead overthought everything and there were several totally unnecessary layers in the data stack that just over complicated everything. That made me think more about whether simple was best. It's definitely easier to understand. – Andy Mar 30 '18 at 10:26

0 Answers0