So, I've looked at some posts about the Specification Pattern here, and haven't found an answer to this one yet.
My question is, in an n-layered architecture, where exactly should me Specifications get "newed" up?
I could put them in my Service Layer (aka, Application layer it's sometimes called... basically, something an .aspx code-behind would talk to), but I feel like by doing that, I'm letting business rules leak out of the Domain. If the Domain objects are accessed some other way (besides the Service Layer), the Domain objects cannot enforce their own business rules.
I could inject the Specification into my Model class via constructor injection. But again, this feels "wrong". I feel like the only thing that should be injected into Model classes are "services", like Caching, Logging, dirty-flag tracking, etc... And if you can avoid it, to use Aspects instead of littering the constructors of the Model classes with tons of service interfaces.
I could inject the Specification via method injection (sometimes referred to as "Double Dispatch"???), and explicitly have that method encapsulate the injected Specification to enforce its business rule.
Create a "Domain Services" class, which would take a Specification(s) via constructor injection, and then let the Service Layer use the Domain Service to coordinate the Domain object. This seems OK to me, as the rule enforced by the Specification is still in the "Domain", and the Domain Service class can be named very much like the Domain object it's coordinating. The thing here is I feel like I'm writing a LOT of classes and code, just to "properly" implement the Specification pattern.
Add to this, that the Specification in question requires a Repository in order to determine whether it's "satisfied" or not.
This could potentially cause performance problems, esp. if I use constructor injection b/c consuming code could call a property that perhaps wraps the Specification, and that, in turn is calling the database.
So any ideas/thoughts/links to articles?
Where is the best place to new up and use Specifications?
Short answer:
You use Specifications mainly in your Service Layer, so there.
Long answer:
First of all, there's two questions here:
Where should your specs live, and where should they be new'd up?
Just like your repository interfaces, your specs should live in the domain layer, as they are, after all, domain specific. There's a question on SO that discusses this on repository interfaces.
Where should they be new'd up though? Well, I use LinqSpecs on my repositories and mostly ever have three methods on my repository:
public interface ILinqSpecsRepository<T>
{
IEnumerable<T> FindAll(Specification<T> specification);
IEnumerable<T> FindAll<TRelated>(Specification<T> specification, Expression<Func<T, TRelated>> fetchExpression);
T FindOne(Specification<T> specification);
}
The rest of my queries are constructed in my service layer. That keeps the repositories from getting bloated with methods like GetUserByEmail, GetUserById, GetUserByStatus etc.
In my service, I new-up my specs and pass them to the FindAll or FindOne methods of my repository. For example:
public User GetUserByEmail(string email)
{
var withEmail = new UserByEmail(email); // the specification
return userRepository.FindOne(withEmail);
}
and here is the Specification:
public class UserByEmail : Specification<User>
{
private readonly string email;
public UserByEmail(string email)
{
this.email = email;
}
#region Overrides of Specification<User>
public override Expression<Func<User, bool>> IsSatisfiedBy()
{
return x => x.Email == email;
}
#endregion
}
So to answer your question, specs are new'd up in the service layer (in my book).
I feel like the only thing that should be injected into Model classes
are "services"
IMO you should not be injecting anything into domain entities.
Add to this, that the Specification in question requires a Repository
in order to determine whether it's "satisfied" or not.
That's a code smell. I would review your code there. A Specification should definitely not require a repository.
A specification is an implementation check of a business rule. It has to exist in the domain layer full stop.
Its hard to give specifics on how you do this as every codebase is different, but any business logic in my opinion needs to be in the domain layer and nowhere else. This business logic needs to be completely testable and coupled loosely from UI, database, external services and other non-domain dependencies. So I would definitely rule out 1, 2, and 3 above.
4 is an option, at least the specification will live in your domain layer. However the newing up of specifications depends really again on the implementation. We usually use depencency injection, hence the newing up of pretty much all of our objects is performed via an IOC container and corresponding bootstrapping code (i.e. we usually wire the application fluently). However we would never directly link business logic directly to e.g. UI model classes and the like. We usually have contours/boundaries between things such as UI and domain. We usually define domain service contracts, which can then be used by outside layers such as the UI etc.
Lastly, my answer is assuming that the system you are working on is at least some way complex. If it is a very simple system, domain driven design as a concept is probably too over the top. However some concepts such as testability, readibility, SoC etc should be respected regardless of the codebase in my opinion.
Related
I am new to DDD and I am trying to apply it with Hexagonal architecture.
I have the following scenario:
A user aggregate
application service
and third party REST API that I need to call before persisting the user to the repository
So I am trying to implement it using ports and adapters, so I have an interface in my application service layer that represents the third party functionality and I have the concrete implementation of that API calling exist in infrastructure layer
as the following image
As you know this interface should take some params and returns specific type, my question is where should I put the types of these params and returned type, should be exist in the infrastructure layer or inside the application service layer?
for example I have the following interface:
class GetSomeDataInput{
customerId string;
userName string;
}
class GetSomeDataResult {
userBlocked boolean;
userAvailable boolean;
}
interface IThirdPartyAPI {
getSomeInfo(GetSomeDataInput input): GetSomeDataResult;
}
As you can see the method should take specific param with specific type and return also specific type, and these classes should be implemented in both the caller side which is application service and also on the receiver side which is the concrete implementation so where should I put these types in infrastructure layer or inside the application layer or put them in a shared directory that could be accessed by both
Sorry I just wrote some pseudo code to explain my question, thank you.
These type are part of your domain, they belong to the application service. Your naming should be independent of the external API. You should name it as what it represents from the application service perspective. Hard to tell based on your code, but something like:
class CustomerIdentifiers {
customerId string;
userName string;
}
class CustomerAvailability {
userBlocked boolean;
userAvailable boolean;
}
interface ICustomerAvailabilityChecker {
getCurrentAvailability(CustomerIdentifiers id): CustomerAvailability;
}
You need to inject the concrete domain service implementation from infrastructure when you instantiate the application service class. At least as far as I understand DDD we are talking about a domain service here: https://badia-kharroubi.gitbooks.io/microservices-architecture/content/patterns/tactical-patterns/domain-application-infrastructure-services-pattern.html
Ports and adapters are good for the scenario, where you have multiple external domain services and you want to call all of them, like here: https://www.kennethlange.com/ports-and-adapters/ Sometimes they just raise events and there is no response or you get the responses on a different channel, not directly with sync behavior. Be aware that calling an external API takes time, so better to use async non-blocking solutions for it. Afaik. java or whatever your language is supports async - await, which would be probably good here, but it depends on your project.
Notice that your question applies to many different architectural styles (DDD, onion, hexagonal, clean, layered). The reason is that the question is actually a fundamental concept in OOP, which is the concept of Interface, and where languages like C# have created some confusion by introducing the keyword interface.
What I mean by that is that a C# interface is not the same as the concept of Interface in all these architectural styles, also known as Contract. As you found in your case, the C# interface defines only one part of the contract. The full contract also contains all the input and output types and optionally custom Exceptions.
Once you see this distinction, it is obvious that all the types used in the contract must be defined in the same place, as they are part of a single unit.
In ports and adapters, onion, etc. the full contract would belong to the Core. In a layered architecture, the full contract would belong to the Data Access Layer.
The advantage of Ports and adapters over layered is that all the names that appear in the contract belong to the Core/Domain, so they align with what domain experts will understand, making the contract a lot more readable. And the translation of these names to technical names which depend on the adapter technology is an internal concern of the adapter itself.
I need an advice on DDD (Domain Driven Design) and implementation of Repository pattern and encapsulation.
To my understanding is that Repository pattern enables me to put all the database access logic in one place and abstract that logic from other parts of application.
On the other side there is orm (Nhibernate, EntityFramework...) with its support for Linq and IQueryable.
My toughts are:
1. If I am using repository then I should not use IQueryable as my return type bust instead use IEnumerable. Because if I use IQueryable then this would allow leaking database code to other application layers (IE would allow other devs to do queries in mvc controller where they don't belong).
But every controls use IQueryable to access data and does this because is easier.
If I use IQueryable as return type of my repository methods then:
- I allow other developers to do database querying in other layers of application (and I think this should not be possible)
- It will leak my domain entities (domain model) to other layers of applications (ie. User interface) but should not, instead DTO should be used.
My question is is IQueryable a good practice in DDD?
I would say it's not a good practice.
Ideally you should have some sort of application layer on top of your domain. If you expose your domain objects directly or through Query object, someone might actually modify it outside of your control.
Personally i like to think of IQueryable as an implementation detail, ideally my domain would not depend on it (in case i want to switch my storage technology it could be a problem).
Most often i'll end up using IQueryable internally inside my repositories implementation. What i usually end up with is implementing generic repository that has a FindBySpecification method, and then have specialized repositories for every Aggregate root that inherits from it. For example:
public interface IRepository<TEntity>
{
TEntity Get(Guid ID);
void Add(TEntity entity);
void Remove(TEntity entity);
void Detach(TEntity entity);
IEnumerable<TEntity> WithSpecification(ISpecification<TEntity> specification);
}
public interface IOrdersRepository : IRepository<Order>
{
IEnumerable<Order> GetCompletedOrdersForAllPreferedCustomers(DateTime orderCompletedAfter);
Order GetOrderBySomeOtherComplicatedMeans();
}
Another aproach is to design your application to follow the CQRS principle.
Then you can have your DomainModel doing it's magic on the command side, and create a readonly model of your data for your client on the query side.
This setup can become really elaborate depending on your requirements, but it can be as simple as two ORM models mapped to the same database (the one on the command side is mapping your domain entities, the one on the query sides maps to simple DTOs ).
Personally I do not feel that exposing EF entities by way of IQueryable across all layers is necessarily a bad thing. But this is just my own opinion. Others may not agree especially if you look at it on the encapsulation perspective. But generally the concept of loose-coupling is a trade-off between complexity and practical gain. By encapsulating IQueryable know that you will loose a lot of practical gain, like the ability to lazy-load for instance.
If your application layer is directly on top of your repository layer, I vote to use IEnnumerable instead of IQueryable. But if you have a service layer in the middle (which I personally prefer to contain all business logic so the repository layer can specialize with data access operations) then I will have the repository return IQueryable and have the service layer return IEnnumerable after it has performed its business logic from the IQueryable object returned by the repository.
These are just my own personal rules:
If you need to encapsulate EF, encapsulate it away only from the application layer. Otherwise, use it as excessively as you need on all layers. EF is very powerful, encapsulating it in the repository layer will make you lose a lot of its power
The application layer should be as thin as possible, it should not perform any further processing on the data it receives from the layer below it. It receives the list and it renders it, that's it.
I have been tasked with the undertaking of translating an application from SharePoint to .NET. I am concerned with doing it the right way, so I got an architecture book to read up on patterns and practices.
I've tried to model everything out using Domain Driven Design. I have a Model that represents my world, a Repository to store it in the database, and a Service layer to interact with UI (which is WebForms, because I have 0 experience in MVC and am already hardly treading water with this undertaking).
I am having difficulty grasping the correct way for the layers to interact. My understanding is that the Model should be the base of everything. It references nothing, other layers reference it.
Question 1: Is that right?
I'm getting really concerned with the Service Layer. I'm noticing that I'm developing a very anemic Model, for two reasons: 1, my Model doesn't reference Repository, so I can't store anything via the Model. 2, I am trying to do things as they happen (ie. I add an object to a list of objects, so I store it in the DB one at a time instead of all at once when the user is done adding the objects). So a lot of the work is being done between the Service and Rep layers, with the Model just being there and looking nice.
I'm starting to worry--I'm early in the development, but I am the one being looked at to be the architect of all this. I don't want a maintenance nightmare (I expect this application will be used for years). As always, time is a concern, and I have not been able to prepare/learn effectively. Any help would be swell. :-)
Model should be the base of everything. It references nothing, other layers reference it.
Question 1: Is that right?
The typical way to enforce separation between the domain model and the persistence system is to define repositories. Persistence however is not a part of the domain model.
Your models should call methods defined by the repository
For example consider this totally fake repository:
// Repository
public class SharepointRepository
{
void SaveWidget(); // Implement
}
So the repository is only concerned with loading and saving data, they don't contain any of your domain logic at all.
However if your model is tightly bound to the repository, you've got a separation of concerns issue.
So in this case, Dependency Injection becomes useful. With the prior example, your model would have to explicitly instantiate SharePointRepository and invoke methods. A cleaner way of doing this so that your model doesn't care is to inject the dependency of your repository at runtime.
namespace YourApp.Domain.Abstract
{
public interface ISharePointRepository
{
void SaveWidget();
}
}
Based on this interface, you could build a concrete implementation and inject the dependency to the concrete implementation at run time.
namespace YourApp.Domain.Concrete
{
public class SqlSharePointRepository : ISharePointRepository
{
void SaveWidget()
{
// Code that Saves the widget using the managed sql provider
}
}
}
So on your web form:
When you are collecting data, your model will be hydrated with data from the form, and will invoke a repository method, however the repository itself would have been injected into the asp.net application at runtime, so you could change SqlSharePointRepository to RavenDbRepository without breaking your app.
To see how to bind your repository in Webforms see this SO Post: How can I implement Ninject or DI on asp.net Web Forms?
With MVC the controller is responsible for the gap you think your are experiencing. But as to your questions and based on your current design, the model should invoke repository operations, however the repository itself should be loosely coupled.
Despite having studied Domain Driven Design for a long time now there are still some basics that I simply figure out.
It seems that every time I try to design a rich domain layer, I still need a lot of Domain Services or a thick Application Layer, and I end up with a bunch of near-anemic domain entities with no real logic in them, apart from "GetTotalAmount" and the like. The key issue is that entities aren't aware of external stuff, and it's bad practice to inject anything into entities.
Let me give some examples:
1. A user signs up for a service. The user is persisted in the database, a file is generated and saved (needed for the user account), and a confirmation email is sent.
The example with the confirmation email has been discussed heavily in other threads, but with no real conclusion. Some suggest putting the logic in an application service that gets an EmailService and FileService injected from the infrastructure layer. But then I would have business logic outside of the domain, right? Others suggest creating a domain service that gets the infrastructure services injected - but in that case I would need to have the interfaces of the infrastructure services inside the domain layer (IEmailService and IFileService) which doesn't look too good either (because the domain layer cannot reference the infrastructure layer). And others suggest implementing Udi Dahan's Domain Events and then having the EmailService and FileService subscribe to those events. But that seems like a very loose implementation - and what happens if the services fail? Please let me know what you think is the right solution here.
2. A song is purchased from a digital music store. The shopping cart is emptied. The purchase is persisted. The payment service is called. An email confirmation is sent.
Ok, this might be related to the first example. The question here is, who is responsible for orchestrating this transaction? Of course I could put everything in the MVC controller with injected services. But if I want real DDD all business logic should be in the domain. But which entity should have the "Purchase" method? Song.Purchase()? Order.Purchase()? OrderProcessor.Purchase() (domain service)? ShoppingCartService.Purchase() (application service?)
This is a case where I think it's very hard to use real business logic inside the domain entities. If it's not good practice to inject anything into the entities, how can they ever do other stuff than checking its own (and its aggregate's) state?
I hope these examples are clear enough to show the issues I'm dealing with.
Dimitry's answer points out some good things to look for. Often/easily you find yourself in your scenario, with a data shoveling from db up to GUI through different layers.
I have been inspired by Jimmy Nilsson's simple advice "Value objects, Value objects and more Value objects". Often people tend to focus to much on Nouns and model them as entity. Naturally you often having trouble in finding DDD behavior. Verbs are easier to associate with behavior. A good thing is to make these Verbs appear in your domain as Value objects.
Some guidance I use for my self when trying to develop the domain (must say that it takes time to construct a rich domain, often several refactoring iterations...) :
Minimize properties (get/set)
Use value objects as much as you can
Expose as little you can. Make you domain aggregates methods intuitive.
Don't forget that your Domain can be rich by doing Validation. It's only your domain that knows how to conduct a purchase, and what's required.
Your domain should also be responsible for validation when your entities make a transition from one state two another state (work flow validations).
I'll give you some examples:
Here is a article I wrote on my blog regarding your issue about anemic Domain http://magnusbackeus.wordpress.com/2011/05/31/preventing-anemic-domain-model-where-is-my-model-behaviour/
I can also really recommend Jimmy Bogard's blog article about entity validations and using Validator pattern together with extension methods. It gives you the freedom to validate infrastructural things without making your domain dirty:
http://lostechies.com/jimmybogard/2007/10/24/entity-validation-with-visitors-and-extension-methods/
I use Udi's Domain Events with great success. You can also make them asynchronous if you believe your service can fail. You also wrap it in a transaction (using NServiceBus framework).
In your first example (just brainstorming now to get our minds thinking more of value objects).
Your MusicService.AddSubscriber(User newUser) application service get a call from a presenter/controller/WCF with a new User.
The service already got IUserRepository and IMusicServiceRepository injected into ctor.
The music service "Spotify" is loaded through IMusicServiceRepository
entity musicService.SignUp(MusicServiceSubscriber newSubsriber) method takes a Value object MusicServiceSubscriber.
This Value object must take User and other mandatory objects in ctor
(value objects are immutable). Here you can also place logic/behavior like handle subscriptionId's etc.
What SignUp method also does, it fires a Domain Event NewSubscriberAddedToMusicService.
It get caught by EventHandler HandleNewSubscriberAddedToMusicServiceEvent which got IFileService and IEmailService injected into it's ctor. This handler's implementation is located in Application Service layer BUT the event is controlled by Domain and MusicService.SignUp. This means the Domain is in control. Eventhandler creates file and sends email.
You can persist the user through eventhandler OR make the MusicService.AddSubscriber(...) method to this. Both will do this through IUserRepository but It's a matter of taste and perhaps how it will reflect the actual domain.
Finally... I hope you grasp something of the above... anyhow. Most important is to start adding "Verbs" methods to entitys and making the collaborate. You can also have object in your domain that are not persisted, they are only there for mediate between several domain entities and can host algorithms etc.
A user signs up for a service. The user is persisted in the
database, a file is generated and saved (needed for the user account),
and a confirmation email is sent.
You can apply Dependency Inversion Principle here. Define a domain interface like this:
void ICanSendConfirmationEmail(EmailAddress address, ...)
or
void ICanNotifyUserOfSuccessfulRegistration(EmailAddress address, ...)
Interface can be used by other domain classes. Implement this interface in infrastructure layer, using real SMTP classes. Inject this implementation on application startup. This way you stated business intent in domain code and your domain logic does not have direct reference to SMTP infrastructure. The key here is the name of the interface, it should be based on Ubiquitous Language.
A song is purchased from a digital music store. The shopping cart
is emptied. The purchase is persisted. The payment service is called.
An email confirmation is sent. Ok, this might be related to the first example. The question here is, who is responsible for orchestrating this transaction?
Use OOP best practices to assign responsibilities (GRASP and SOLID). Unit testing and refactoring will give you a design feedback. Orchestration itself can be part of thin Application Layer. From DDD Layered Architecture:
Application Layer: Defines the jobs the software is supposed to do and directs the
expressive domain objects to work out problems. The tasks this layer
is responsible for are meaningful to the business or necessary for
interaction with the application layers of other systems.
This layer is kept thin. It does not contain business rules or
knowledge, but only coordinates tasks and delegates work to
collaborations of domain objects in the next layer down. It does not
have state reflecting the business situation, but it can have state
that reflects the progress of a task for the user or the program.
Big part of you requests are related to object oriented design and responsibility assignment, you can think of GRASP Patterns and This, you can benefit from object oriented design books, recommend the following
Applying UML and Patterns
Does it make sense to group all Interfaces of your Domain Layer (Modules, Models, Entities, Domain Services, etc) all within the Infrastructure layer? If not, does it make sense to create a "shared" project/component that groups all of these into a shared library? After all, the definition of "Infrastructure Layer" includes "shared libraries for Domain, Application, and UI layers".
I am thinking of designing my codebase around the DDD layers: UI, Application, Domain, Infrastructure. This would create 4 projects respectfully. My point is, you reference the Infrastructure Layer from the Domain Layer. But if you define the interfaces in the Domain Layer project, say for IPost, then you'll have a circulur reference when you have to reference the Domain Layer project from the Infrastructure project when you are defining the IPostRepository.Save(IPost post) method. Hence, the idea of "define all Interfaces in the Shared library".
Perhaps the repositories should not expect an object to save (IPostRepository.Save(IPost post); but instead, expect the params of the object (that could be a long set of params in the Save() though). Given, this could be an ideal situation that shows when an object is getting overly complex, and additional Value Objects should be looked into for it.
Thoughts?
Concerning where to put the repositories, personally I always put the repositories in a dedicated infrastructure layer (e.g . MyApp.Data.Oracle) but declare the interfaces to which the repositories have to conform to in the domain layer.
In my projects the Application Layer has to access the Domain and Infrastructure layer because it’s responsible to configure the domain and infrastructure layer.
The application layer is responsible to inject the proper infrastructure into the domain. The domain doesn’t know to which infrastructure it’s talking to, it only knows how to call it. Of course I use IOC containers like Structuremap to inject the dependencies into the domain.
Again I do not state that this is the way DDD recommends to structure your projects, it’s just the way, I architecture my apps.
Cheers.
I’m quiet new in DDD so don’t hesitate to comment if you disagree, as you I’m here to learn.
Personally I don’t understand why you should reference the infrastructure layer from your domain. In my opinion the domain shouldn’t be dependent on the infrastructure. The Domain objects should be completely ignorant on which database they are running on or which type of mail server is used to send mails. By abstracting the domain from the infrastructure it is easier to reuse; because the domain don’t know on which infrastructure its running.
What I do in my code is reference the domain layer from my infrastructure layer (but not the opposite). Repositories know the domain objects because their role is to preserve state for the domain. My repositories contains my basic CRUD operations for my root aggregates (get(id), getall(), save(object), delete(object) and are called from within my controllers.
What I did on my last project (my approach isn’t purely DDD but it worked pretty well) is that I abstracted my Repositories with interfaces. The root aggregates had to be instantiated by passing a concrete type of a Repository:
The root aggregate had to be instantiated through a repository by using the Get(ID) or a Create() method of the repository. The concrete Repository constructing the object passed itself so that the aggregate could preserve his state and the state of his child objects but without knowing anything of the concrete implementation of the repository.
e.g.:
public class PostRepository:IPostRepository
{
...
public Post Create()
{
Post post=new Post(this);
dbContext.PostTable.Insert(post);
return post;
}
public Save(post)
{
Post exitingPost=GetPost(post.ID);
existingPost = post;
dbContext.SubmitChanges();
}
}
public class Post
{
private IPostRepository _repository
internal Post(IPostRepository repository)
{
_repository = repository;
}
...
Public Save()
{
_repository.Save(this);
}
}
I would advise you to consider Onion architecture. It fits with DDD very nicely. The idea is that your repository interfaces sit in a layer just outside Domain and reference Entities directly:
IPostRepository.Save(Post post)
Domain does not need to know about repositories at all.
Infrastructure layer is not referenced by Domain, or anybody else and contains concrete implementations of repositories among other I/O-related stuff. The common library with various helpers is called Application Core in this case, and it can be referenced by anyone.