Bounded Context and Generic Repository with Entity Framework and wiring with Simple injector IoC

c# entity-framework-6 generics repository-pattern simple-injector

Question

Been reading a lot on StackOverflow and couldn't find any question/answer exact similar to this one. Try to keep it short.

My key problem is how to design a Generic Repository when you have several bounded contexts. I have been using Generic repository before a lot but then I usually close them through for example

public class CustomerRepository : Repository<Customer>

But now I would like to skip these custom queries and aiming instead for using queryhandlers for custom queries like "GetCustomerbyOrderNumber...." and let Repositories be responsible for just working with one entity, in this example Customer.

But when using Bounded Context, which I have done before, I usually register each Entity Framework DBContext per Bounded Context with my IoC (used Castle, AutoMapper and now Simple Injector). But when trying to go for a pure Open Generic Repository approach...

 public class Repository<TEntity> : IRepository<TEntity>
    where TEntity : Entity, IAggregateRoot
{
    #region Members

    private readonly IQueryableUnitOfWork _unitOfWork;

    #endregion

    #region Constructor

    /// <summary>
    ///     Create a new instance of repository
    /// </summary>
    /// <param name="unitOfWork">Associated Unit Of Work</param>
    protected Repository(IQueryableUnitOfWork unitOfWork)
    {
        if (unitOfWork == null)
            throw new ArgumentNullException("unitOfWork");

        _unitOfWork = unitOfWork;
    }

I don't know how to manage Simple Injector to understand what Dbcontext to use. The scenario Will probably be that a ICommandHandler will be injected into a MVC controller. The Implementation AddCustomerCommandHandler will have IRepository injected into constructor. BUT here comes the problem. The implementation Repository takes IQuerableUnitOfWork as dependcy (All Bounded Contexts inherits from a BaseContext that inherits from interface IQuerableUnitOfWork. So that all DBContexts are a IQuerableUnitOfWork).

Somehow I need tell Simple injector to inject ANiceBoundedContexOne (just an example context) into Repository when used with command handlers in the same Bounded context (located in another assembly though). And then using ANiceBoundedContexTwo injected into Repository when using command handlers for that bounded context.

I've done some research and reading and not exactly sure of the capability of Simple Injector but I can see some solution paths:

1) Make a factory and register that in SI. Inject that factory into CommandHandlers and let them get the appropriate Repository.

2) Make more Context specific interface. IContextOneRepository if I refer to example above. Which means that if I have three Bounded Context infrastructure assemblies they can all have their IContextOneRepository, IContextTwoRepository and IContextThreeRepository (name sucks but its just an example). And the Repository implementation is located in a Shared Kernel class library. Simple injector will register three interfaces for that implementation but with different DBContext injected into Repository constructor.

Is there any other nice and smooth way that I haven't thought of?

And have you actually done any of the solutions above with simple injector and how did that worked out?

1
1
4/23/2014 8:35:30 AM

Popular Answer

You don't use a generic repository, period! At most you use a generic repository interface where T is Domain Entity,never EF entity. You don't expose EF or bits of it, it defeats the Repository's purpose (decoupling the Domain from persistence details).

A repository works with aggregate roots (AR) which are valid ONLY in a specific bounded context (BC). A BC is defined by the Domain and it doesn't care about persistence or other implementation detail. Because a BC is an abstract DDD concept, not an actually class. In your BCs do you have the same ARs? If so, it is possible you got the wrong model or some BCs can be merged. Also it DOES matter if you're using CQRS, since you would care only for changing the model (command) and not for queries.

It's a bit hard for me to understand your actual situation as the code seems quite messy, but these are my thoughts:

You have one or more ARs defined. Each AR has a corresponding repository, implemented in DAL, repository which uses EF. The app gets/saves only AR from those repositories (no EF in sight). A Repo for a specific AR doesn't care about other ARs (at least from the interface point of view, it's fine if you want to use the same implementation for all).

Your question is about how to use a Di Container but it's like asking: what chainsaw brand is better to cut the tree branch I'm standing on. None, the objective is wrong to start with.

No offense, but I get the feeling you are using a very flawed version of DDD i.e you're not doing proper DDD and as a result, your code is pretty complicated and it seems low maintainability.

2
4/23/2014 2:30:39 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow