I assigned a POC project to someone where I asked to implement both Command Query Responsibility Segregation, Inversion of Control (with Dependency Injection) and Repository pattern.  Someone gave me a POC solution project but I am not sure whether this is the way it is done. I will brief here about the POC projectThe project is a simple 3-tier application  the Presentation Layer (PL), the Business Logic Layer  (BLL) and the Data Access Layer (DAL); each tier being a separate projectThe Presentation Layer is a Web Application, the BLL and DAL are class library projectsIn the Business Layer, there are defined Repository Interfaces. The reference of BLL library is added to DAL project and inside the DAL project there are concrete classes that implement the Repository Interfaces. This is how Inversion of Control is appliedSince Command-Query-Responsibility-Segregation is done, the repository interfaces in the Business Layer only declare Add/Update and Delete methods. For read, there are Read interfaces directly in the DAL and in the DAL there are concrete classes that implement these interfaces.The Presentation Layer contains reference to both the BLL library and the DAL library. Calls to Add/Update/Delete are routed through the BLL to the DAL while any read is done directly from the DAL. I believe this conforms to Command-Query-Responsibility-Segregation concept of bypassing the BLL for doing reads.Here is an illustration of how this is all setup. There are three projectsNW.WebNW.BusinessNW.DataAccessBelow is a snapshot of code in the different layers.-- NW.Web --// A class in the Presentation Layerpublic class CustomerPage {    // Business layer Interface from  NW.Business namespace    private ICustomerBusiness ICustB;    //DAL Read interface from NW.DataAccess.Read namepsace    private ICustomerRead<Guid> ICustR;    //Constructor for the Customer Page that uses Constructor Injection  public CustomerPage(ICustomerBusiness ICustB, ICustomerRead<Guid> ICustR)    {        this.ICustB = ICustB;        this.ICustR = ICustR;    }}-- NW.Business --//Declaration of business interface in the Business Layerinterface ICustomerBusiness{    void Persist();}// A class in the Business Layer that implements the business interfacepublic class Customer: ICustomerBusiness {    //Repository interface object that will be injected by Constructor Injection.    private ICustomerRepository ICustRep;    public Customer(ICustomerRepository ICustRep)    {        this.ICustRep = ICustRep;    }    public void Persist()    {            ICustRep.AddOrUpdate();    }}//Declaration of Repository interface in the Business Layerpublic interface ICustomerRepository{    void AddOrUpdate();    void Delete();}-- NW.DataAccess--public class CustomerRepository : ICustomerRepository{    public void AddOrUpdate()    {        //implementation of Add or Update    }    public void Delete()    {        //implementation of Delete    }}//A Read interface in the Data Access Layerinterface ICustomerRead<T>{   // A read is returned as DTO since in Database this may map to more than 1 table    CustomerDTO GetCustomerDetails(T id);}// An implementation of the Read Interface in the Data Access Layernamespace NW.DataAccess.Read{    public class CustomerRead<T> : ICustomerRead<T>     {        public CustomerDTO GetCustomerDetails(T id)        {           //implementation here        }    }}My gut feeling is that there is something wrong here. It seems CQRS or at least the above implementation does not address some requirementsThe Customer Business object (Customer class) may need to read from Database for its internal purpose (like initializing variables etc). With read directly defined in DAL layer, the only way to do this would be to reference the DAL dll in the BLL. But this would create circular reference and go against the IOC that is doneWhat happens when there is some common Read requirement across all business objects ?
CQRS with Repository pattern and Inversion of Control (with DI)
repository;n tier;cqrs;inversion of control