views:

277

answers:

3

Hi All, After reading Eriv Evan's Domain driven design also i have few doubts. I searched but no where i could able to find satisfying answers. Please let me know if anyone of you have clear understanding below questions.

My concerns are

  1. Repository is for getting already existing aggregates from DB,Web service . If yes, Can Repository also have transaction calls on this entity (i.e Transfer amount,send account details ...etc)

  2. Can Entity have Methods which have business logic in which it calls infrastructure Layer services for sending emails .. logs etc (Entity methods calling IS services direclty).

  3. Repository implementation and Factory classes will reside in Infrastrucure Layer. is that correct statement ?

  4. Can UI layer (controller) call Repositry methods directly ? or should we call these from Application layer ?

There are still lot many confusion in my mind ... please guide me ... Books i am using Eric Evan's domain driven desing ...... .NET Domain-Driven Design with C#

please suggest

+5  A: 
  1. There is a lot of debate about whether Repositories should be read-only or allow transactions. DDD doesn't dictate any of these views. You can do both. Proponents of read-only Repositories prefer Unit of Work for all CUD operations.

  2. Most people (self included) consider it good practice that Entities are Persistent-Ignorant. Extending that principle a bit would indicate that they should be self-contained and free of all infrastructure layer services - even in abstract form. So I would say that calls to infrastructure services belong in Service classes that operate on Entities.

  3. It sounds correct that Repository implementations and Factories (if any) should reside in the infrastructure layer. Their interfaces, however, must reside in the Domain Layer so that the domain services can interact with them without having dependencies on the infrastructure layer.

  4. DDD doesn't really dictate whether you can skip layers or not. Late in the book, Evans talks a bit about layering and calls it Relaxed Layering when you allow this, so I guess he just sees it as one option among several. Personally I'd prefer to prevent layer skipping, because it makes it easier to inject some behavior at a future time if calls already go through the correct layers.

Mark Seemann
+6  A: 
  1. Personally, in my latest DDD-project, I use a Unit Of Work that holds an NHibernate session. The UoW is ctor injected in the repositories, giving them the single responsible of Add, Remove and Find.

  2. Evans has stated that one piece of the puzzle that's missing in the DDD book is «Domain Events». Using something like Udi Dahan's DomainEvents will give you a totally decoupled architecture (the domain object simple raises an event). Personally, I use a modified version of Domain Events and StructureMap for the wiring. It works great for my needs.

  3. I recommend, based on other recommendations, that the Repository interfaces be a part of the model, and their implementations be a part of the infrastructure.

  4. Yes! I've personally worked on three DDD web projects where services and repositories were injected to the presenters/controllers (ASP.NET/ASP.NET MVC) and it made a lot of sense in our context.

Martin R-L
Thanks Martin, for your suggestions ...... i think i have to start implementing the design instead of thinking lot of DDD , i assume my Domain design will get manu iterations once i start building the application
prakash
A: 
  1. The repository should only be for locating and saving entities, there should not be any business logic in that layer. For example:

    repository.TransferAmount(amount, toAccount); // this is bad

  2. Entities can do things like send emails as long as they depend on abstractions defined in your domain. The implementation should be in your infrastructure layer.

  3. Yes, you put your repository implementation in your infrastructure layer.

  4. Can UI layer (controller) call Repositry methods directly ? or should we call these from Application layer ?

Yes, I try to follow this pattern for the most part:

[UnitOfWork]
public ActionResult MyControllerAction(int id)
{
    var entity = repository.FindById(id);
    entity.DoSomeBusinessLogic();
    repository.Update(entity);
}
Michael Valenty