Should I always go through the services when I try to follow DDD?
Or can I use a repository directly to get a domain object?
Should I always go through the services when I try to follow DDD?
Or can I use a repository directly to get a domain object?
Personally, I don't like seeing repositories in controllers, or in the presentation layer in general. But I've seen it many times and there's nothing wrong with it in the context of DDD.
I think the answer is that it depends on how big your project is. A service layer is more often found in more complex projects. Whereas simpler MVC websites for example just use repositories directly.
Or can I use a repository directly to get a domain object?
You definitely can. It's precisely the goal of repositories. I wonder what kind of a service you'd otherwise use for that (except in the specific context of an SOA or web service based architecture).
After completing my first project structured using the DDD principles :D, I found that it is useful to have both domain services and repositories that are available for the application layer to consume.
KEY POINT: The application layer may be your WCF services or the code in your web services if you're using that architecture. It all depends on your implementation. If it suits your implementation, your application layer may be the same as your presentation layer, thus having the application layer code in your contollers or web forms code behind.
Repositories function like in-memory collections. To the application layer, the code should look like you're just using any old collection.
Domain Services function more like processors or accessors to information that will never be updated, maybe processed, but not updated directly. To the application layer, the code should look like you're just using any old web service.
That being said, I will explain more with some examples:
Repositories
My repositories actually inherit from a generic collection typed with an implementation object I created that encapsulates the database key and the business model together. Using this approach, I can define an indexer in my interface such as
BusinessObject this[int index];
and I can have a getter that will return the business object based on the index of the underlying collection and a setter that will lookup the data key from the underlying collection and save the object to the database. This makes the application code extremely simple, for example
IBusinessObjectRepository repository = new SqlBusinessObjectRepository(sqlString);
BusinessObject obj = repository[0]; //Get first object in the list.
//Make some changes to the business object by setting properties or calling methods to process business logic.
repository[0] = obj; //Save the object back to the database.
Services
I use services to retrieve lists of entities and value objects that I am not going to edit individually and, in my case, are only used as available selections or values when calling methods on the aggregate root. Generally, I cache this information on the web server. This is not the only use for a domain service, just my example. The application layer code still remains relatively simple.
IBusinessService service = new ImplBusinessService(implementationArgs);
List<BusinessObject> objsToCache = service.GetBusinessObjects();
//cache the objects on the web server.
In conclusion and from my understanding of DDD principles, the application layer should be able to access business objects from either services or repositories. The choice between them comes down to what fits best within the domain model.