Could my domain model reference my repository interfaces? or better yet, containing my repositories definitions?
I ask because I was thinking about what I read on the limbo of internet that says that a model shouldn't know about its persistence, but I think if the repository exists due the model, I mean, to handle specific needs of its model, why not the model project define it?
Is it a problem/ bad design if I do the following?
public interface ISomethingThatNeedToBeAprovedRepository
{
void Save(SomethingThatNeedToBeAproved somethingThatNeedToBeAproved);
}
public class SomethingThatNeedToBeAproved
{
public int Status {get;set;}
public string Reason {get;set;}
public ISomethingThatNeedToBeAprovedRepository Repository{ get; set;}
public void Aprove(status, reason)
{
DoSomeAsserts();
Status = status;
Reason = reason;
Repository.save(this);
}
}
Yes, it can!
At given point you need to persist your aggregate so a repository is needed. I use to take IRepository inside my domain model, while infratructure details of Repository in another project.
No, it will be a bad design.
The domain model (this domain layer) should totally be independent of any other layer.
The repository interface and implementation should refer to the domain model to save and perform storage operations.
The answer is really it depends.
As #marianoc84 said, at some point, the application would really need to concern about persistence. The question here, is the particular domain model needs a concern about data persistence?
If it does, then it is make sense to put a repository inside the model.
On other side, having the repository inside 'may' makes unit test more challenging, and just be aware that generally speaking, the domain model could be distributed anywhere to pretty much up to application layer.
However, if the model does not really need to concern about persistence, then you don't really need a repository inside. The persistence could be done on other places such as having an 'ApprovalServices' which in this case, there could be several A, B, C, D and E that could be approved and have this to be persisted.
Related
I think I've read 16,154 questions, blog posts, tweets, etc about DDD and best practices. Apologies for yet another question of that type. Let's say I have three tables in my database, User, Department, and UserDepartment. All very simple. I need to build a hierarchy showing what departments a user has access to. The issue is that I also need to show the parent departments of those that they have access to.
Is it best to have a GetDepartments() method on my user class? Right now I have a user service with GetDepartments(string userName), but I don't feel like that is the optimal solution. If user.GetDepartments() is preferred then how do I get access the repository to get the parent departments for those that the user has access to?
Don't think it matters, but I'm using the Entity Framework.
public class User
{
[Key]
public int UserId { get; private set; }
[Display(Name = "User Name")]
public string UserName { get; private set; }
[Display(Name = "Email")]
public string Email { get; private set; }
[Display(Name = "UserDepartments")]
public virtual ICollection<UserDepartment> UserDepartments { get; private set; }
public List<Department> GetDepartments()
{
// Should this be here? and if so, what's the preferred method for accessing the repository?
}
}
DDD is more about the behavior, which also mean it is TDA (tell, don't ask) oriented.
Normally you structure your aggregates in a way that you tell them what to do, not ask for information.
Even more, if some extra information is required by the aggregate in order to perform its behavior, it is typically not their job to figure out where to get this information from.
Now, when you are saying that your User aggregate has GetDepartments method, it raises a bell. Does the aggregate need this information in order to perform any kind of behavior? I don't think so, it is just you wanting some data to display.
So what I see here is that you are trying to structure your aggregates against your data tables, not against the behavior.
This is actually #2 error when applying DDD (#1 is not thinking about bounded contexts).
Again, aggregates represent business logic and behavior of your system. Which means that you don't have to read from aggregates. Your read side can be done much easier - just make a damn query to the DB.
But once you need to ask your system to do something - now you do it through aggregates: AppService would load one from the repository and call its behavior method.
That's why normally you don't have properties in your aggregates, just methods that represent behavior.
Also, you don't want your aggregates to be mapped to the data tables anyhow, it is not their job, but the job of repositories. Actually, you don't want your domain to have dependencies on anything, especially infrastructure.
So if you want to go for DDD direction then consider the following:
Structure your aggregates to encapsulate behaviors, not represent data tables
Don't make your domain dependant on infrastructure, etc.
Make repositories to be responsible to load/save aggregates. Aggregates themselves should know nothing about persistence, data structure, etc.
You don't have to read data through aggregates.
Think of #4 as your system has two sides: the "read" side when you just read the data and show them in the UI, and the "command" side when you perform actions.
The first one (read) is very simple: stupid queries to read the data in a way you want it. It doesn't affect anything because it is just reading, no side effects here.
The second one is when you make changes and that is going through your domain.
Again, remember the first rule of DDD: if you don't have business logic and behavior to model then don't do DDD.
As I understand, the Bounded Context can have modules, the modules can have many aggregate roots, the aggregate root can have entities. For the persistence, each aggregate root should have a repository.
With the numerous aggregate roots in a large project, is it okay to use a Generic Repository, one for ready only and one for update? Or should have separate repository for each aggregate root which can provide better control.
In a large complex project, I wouldn't recommend using a generic repository since there will most likely be many specific cases beyond your basic GetById(), GetAll()... operations.
Greg Young has a great article on generic repositories : http://codebetter.com/gregyoung/2009/01/16/ddd-the-generic-repository/
is it okay to use a Generic Repository, one for ready only and one for update?
Repositories generally don't handle saving updates to your entities, i.e. they don't have an Update(EntityType entity) method. This is usually taken care of by your ORM's change tracker/Unit of Work implementation. However, if you're looking for an architecture that separates reads from writes, you should definitely have a look at CQRS.
Pure DDD is about making implicit explicit, ie : not using List(), but rather ListTheCustomerThatHaveNotBeSeenForALongTime().
What is at stake here is a technical implementation. From What I know, domain driven design does not provide technical choices.
Generic repository fits well. Your use of this generic repository might not fit the spirit of ddd though. It depends on your domain.
On some of the sample DDD applications that are published on the web, I have seen them have a base repository interface that each aggregate root repository inherits from. I, personally, do things a bit differently. Because repositories are supposed to look like collections to the application code, my base repository interface inherits from IEnumerable so I have:
public interface IRepository<T> : IEnumerable<T> where T : IAggregateRoot
{
}
I do have some base methods I put in there, but only ones that allow reading the collection because some of my aggregate root objects are encapsulated to the point that changes can ONLY be made through method calls.
To answer your question, yes it is fine to have a generic repository, but try not to define any functionality that shouldn't be inherited by ALL repositories. And, if you do accidentally define something that one repository doesn't need, refactor it out into all of the repository interfaces that do need it.
EDIT: Added example of how to make repositories behave just like any other ICollection object.
On the repositories that require CRUD operations, I add this:
void Add(T item); //Add
void Remove(T item); //Remove
T this[int index] { set; } //or T this[object id] { set; } //Update
Thanks for the comments. The approach that I took was separated the base repository interface into ReadOnly and Updatable. Every aggregate root entity will have it's own repository and is derived from Updatable or readonly repository. The repository at the aggregate root level will have it's own additional methods. I'm not planning to use a generic repository.
There is a reason I choose to have IReadOnlyRepository. In the future, I will convert the query part of the app to a CQRS. So the segregation to a ReadOnly interface supertype will help me at that point.
I'm looking for some advice on how much I should be concerned around avoiding the anemic domain model. We are just starting on DDD and are struggling with analysis paralysis regarding simple design decisions. The latest point we are sticking on is where certain business logic belongs, for example we have an Order object, which has properties like Status etc. Now say I have to perform a command like UndoLastStatus because someone made a mistake with an order, this is not as simple as just changing the Status as other information has to be logged and properties changed. Now in the real world this is a pure administration task. So the way I see it I have two options I can think of:
Option 1: Add the method to order so something like Order.UndoLastStatus(), whilst this kinda make sense, it doesn't really reflect the domain. Also Order is the primary object in the system and if everything involving the order is placed in the order class things could get out of hand.
Option 2: Create a Shop object, and with that have different services which represent differant roles. So I might have Shop.AdminService, Shop.DispatchService, and Shop.InventoryService. So in this case I would have Shop.AdminService.UndoLastStatus(Order).
Now the second option we have something which reflects the domain much more, and would allow developers to talk to business experts about similar roles that actually exists. But its also heading toward an anemic model. Which would be the better way to go in general?
Option 2 would lead to procedural code for sure.
Might be easier to develop, but much harder to maintain.
Now in the real world this is a pure administration task
"Administration" tasks should be private and invoked through public, fully "domain`ish" actions. Preferably - still written in easy to understand code that is driven from domain.
As I see it - problem is that UndoLastStatus makes little sense to domain expert.
More likely they are talking about making, canceling and filling orders.
Something along these lines might fit better:
class Order{
void CancelOrder(){
Status=Status.Canceled;
}
void FillOrder(){
if(Status==Status.Canceled)
throw Exception();
Status=Status.Filled;
}
static void Make(){
return new Order();
}
void Order(){
Status=Status.Pending;
}
}
I personally dislike usage of "statuses", they are automatically shared to everything that uses them - i see that as unnecessary coupling.
So I would have something like this:
class Order{
void CancelOrder(){
IsCanceled=true;
}
void FillOrder(){
if(IsCanceled) throw Exception();
IsFilled=true;
}
static Order Make(){
return new Order();
}
void Order(){
IsPending=true;
}
}
For changing related things when order state changes, best bet is to use so called domain events.
My code would look along these lines:
class Order{
void CancelOrder(){
IsCanceled=true;
Raise(new Canceled(this));
}
//usage of nested classes for events is my homemade convention
class Canceled:Event<Order>{
void Canceled(Order order):base(order){}
}
}
class Customer{
private void BeHappy(){
Console.WriteLine("hooraay!");
}
//nb: nested class can see privates of Customer
class OnOrderCanceled:IEventHandler<Order.Canceled>{
void Handle(Order.Canceled e){
//caveat: this approach needs order->customer association
var order=e.Source;
order.Customer.BeHappy();
}
}
}
If Order grows too huge, You might want to check out what bounded contexts are (as Eric Evans says - if he had a chance to wrote his book again, he would move bounded contexts to the very beginning).
In short - it's a form of decomposition driven by domain.
Idea is relatively simple - it is OK to have multiple Orders from different viewpoints aka contexts.
E.g. - Order from Shopping context, Order from Accounting context.
namespace Shopping{
class Order{
//association with shopping cart
//might be vital for shopping but completely irrelevant for accounting
ShoppingCart Cart;
}
}
namespace Accounting{
class Order{
//something specific only to accounting
}
}
But usually enough domain itself avoids complexity and is easily decomposable if You listen to it closely enough. E.g. You might hear from experts terms like OrderLifeCycle, OrderHistory, OrderDescription that You can leverage as anchors for decomposition.
NB: Keep in mind - I got zero understanding about Your domain.
It's quite likely that those verbs I'm using are completely strange to it.
I would be guided by the GRASP principles. Apply the Information Expert design principle, that is you should assign the responsibility to the class that naturally has the most information required to fulfill the change.
In this case, since changing the order status involves other entities, I would make each of these low-level domain objects support a method to apply the change with respect to itself. Then also use a domain service layer as you describe in option 2, that abstracts the whole operation, spanning multiple domain objects as needed.
Also see the Facade pattern.
I think having a method like UndoLastStatus on the Order class feels a bit wrong because the reasons for its existence are in a sense outside of the scope of an order. On the other hand, having a method which is responsible for changing the status of an order, Order.ChangeStatus, fits nicely as a domain model. The status of an order is a proper domain concept and changing that status should be done through the Order class, since it owns the data associated with an order status - it is the responsibility of the Order class to keep itself consistent and in a proper state.
Another way to think of it is that the Order object is what's persisted to the database and it is the 'last stop' for all changes applied to an Order. It is easier to reason about what a valid state for an order might be from the perspective of an Order rather than from the perspective of an external component. This is what DDD and OOP are all about, making it easier for humans to reason about code. Furthermore, access to private or protected members may be required to execute a state change, in which case having the method be on the order class is a better option. This is one of the reasons why anemic domain models are frowned upon - they shift the responsibility of keeping state consistent away from the owning class, thereby breaking encapsulation among other things.
One way to implement a more specific operation such as UndoLastStatus would be to create an OrderService which exposes the domain and is how external components operate upon the domain. Then you can create a simple command object like this:
class UndoLastStatusCommand {
public Guid OrderId { get; set; }
}
An the OrderService would have a method to process that command:
public void Process(UndoLastStatusCommand command) {
using (var unitOfWork = UowManager.Start()) {
var order = this.orderRepository.Get(command.OrderId);
if (order == null)
throw some exception
// operate on domain to undo last status
unitOfWork.Commit();
}
}
So now the domain model for Order exposes all of the data and behavior that correspond to an Order, but the OrderService, and the service layer in general, declare the different kind of operations that are performed on an order and expose the domain for utilization by external components, such as the presentation layer.
Also consider looking into the concept of domain events which considers anemic domain models and ways of improving them.
It sounds like you are not driving this domain from tests. Take a look at the work of Rob Vens, especially his work on exploratory modeling, time inversion and active-passive.
i've read a blog about DDD from Matt Petters
and according and there it is said that we create a repository (interface) for each entity and after that we create a RepositoryFactory that is going to give instances (declared as interfaces) of repositories
is this how project are done using DDD ?
i mean, i saw projects that i thought that they use DDD but they were calling each repository directly, there was no factory involved
and also
why do we need to create so much repository classes, why not use something like
public interface IRepository : IDisposable
{
T[] GetAll();
T[] GetAll(Expression<Func> filter);
T GetSingle(Expression<Func> filter);
T GetSingle(Expression<Func> filter, List<Expression<Func>> subSelectors);
void Delete(T entity);
void Add(T entity);
int SaveChanges();
}
i guess it could be something with violating the SOLID principles, or something else ?
There are many different ways of doing it. There's is not single 'right' way of doing it. Most people prefer a Repository per Entity because it lets them vary Domain Services in a more granular way. This definitely fits the 'S' in SOLID.
When it comes to factories, they should only be used when they add value. If all they do is to wrap a new operation, they don't add value.
Here are some scenarios in which factories add value:
Abtract Factories lets you vary Repository implementations independently of client code. This fits well with the 'L' in SOLID, but you could also achieve the same effect by using DI to inject the Repository into the Domain Service that requires it.
When the creation of an object in itself is such a complex operation (i.e. in involves much more than just creating a new instance) that it is best encapsulated behind an API.
I have implemented the command side of DDD using the domain model and repositories, but how do I implement the query side?
Do I create an entirely new domain model for the UI, and where is this kept in the project structure...in the domain layer, the UI layer, etc?
Also, what do I use as my querying mechanism, do I create new repositories specifically for the UI domain objects, something other than repositories, or something else?
From my understanding of CQRS you would create a set a DTOs that fulfil the requirements of the user interface screens or applications that may need to consume them.
Where this exists in the project is based on the requirements as it would depend if you were going to expose these DTOs via web services.
In which case I wouldn't put it in the Web Layer but rather in the Application layer or a dedicated Façade layer.
Then you would have a read only repository or data access layer which populates the DTOs directly. I think that the Query side of things should be optimized for read performance in which case direct queries/stored procedures on database views or tables and SqlDataReaders would do the best job here. But it would definitely be worth abstracting this access behind an interface so you can add a cached implementation later down the track.
If you're using an ORM and want to map from your Domain Entities to the DTOs then you could have a generic QueryRepository which has methods which take an ISpecification or similar construct for defining your queries then a DtoAssembler object for creating the Dtos from your Domain objects.
Then have an implementation has a first class object for each of the queries you are going to perform.
Here's a fairly contrived example but I hope it gives you an idea.
public interface ISpecification<T>
{
Expression<Func<T, bool>> Predicate { get; }
}
public class ActiveCustomersSpecification : ISpecification<Customer>
{
private Expression<Func<Customer, bool>> predicate;
public ActiveCustomersSpecification()
{
predicate = c => c.IsActive;
}
#region ISpecicfication<Customer> Members
public Expression<Func<Customer, bool>> Predicate
{
get { return predicate; }
}
#endregion
}
public interface IQueryRepository<T>
{
IQueryable<T> GetQuery(ISpecification<T> specification);
IEnumerable<T> FindAllBy(ISpecification<T> specification);
}
public class CustomerDtoAssembler
{
public CustomerDto AssembleFrom(Customer customer)
{
var customerDto = new CustomerDto
{
Id = customer.Id
};
return customerDto;
}
}
I think willbt has given you a really good starting point.
I would add that if you do opt to continue to use the ORM as the data-access strategy for queries you would be well-advised to consider defining a fetching strategy tailored to the data you expect you'll need to access (I'm thinking specifically about NHibernate here, by the way). What this means is you can decide whether to lazy-load or to eager-load the objects and collections associated with a particular Aggregate Root object.
The NCommon project by Ritesh Rao offers an excellent (work in progress) demonstration of how to define a different fetching strategy for different purposes.
Ritesh explains it really well in his blog.
Go ahead and have a look at the source:
here's the IFetchingStrategy interface
and this shows the use of fetching strategies in a unit test
In the test 'Repository_For_Uses_Registered_Fetching_Strategies' the call to
NHRepository<Order>().For<NHRepositoryTests>()
...causes the fetching strategies registered against the NHRepositoryTests class to be used, and therefore the OrderItems and Products will be eager loaded without messing about with NHibernate mapping configurations.