Reputation: 103
I am sorry if the question is trivial and already anwsered. I have been looking for an anwser, but all I was able to find were images and UMLs of the given situation without explaination. I have started reading the .NET Domain-Driven-Design book and I find myself hitting a brick wall in the start. My problem is that the author suggest creating a base class for Entities, this base class is placed in the Infrasturcture layer. This class will be inherited by all Entity classes in the Domain. That seems very uncommon and counter intuitive , at least to me. So I am trying to follow the book, but I can't understand why is this presented as a good idea, because I have a fear of circular dependency in the future development of the project, and can't understand why should the Entity Base class be outside of the Domain. Thank you.
I am afraid of cyclic dependency because in the chapter that preceeds the implementation phase the Author describes a downflow of dependancy. Starting from UI ->Application layer -> Domain while Infrastructure layer is not referencing anyone, but everyone references the Infrastructure layer. So I am having trouble understanding why should the Domain refrence the Infastructure? Regarding DDD (I assume) the Domain should be independant of other layers. So I just wanted to ask is the Domain -> Infrasturcture dependancy a common thing, or should there be a better/cleaner solution ? The book I'm reading is called .NET Domain Driven Design in C# Problem-Design-Solution
This link provides an image that depicts the architecture of the design at hand. The same image is provided in the book that I am following. https://ajlopez.wordpress.com/2008/09/12/layered-architecture-in-domain-driven-design/. Thank you for your feedback and your answers.
Upvotes: 1
Views: 1299
Reputation: 644
Domain Driven Development architecture is a layered design that can be really good when you need to separate business rules (user requirements) from the rest of the project.It puts the Domain in the center of the development.
It is quite usual to see concepts such as Dependency Injection and Inversion of Control when implementing a DDD architecture. The example below is one of the many ways to put Domain in the center of the application, its just for you to have something in mind.
Infrastructure: Implements all the interfaces created at domain level. This layer is responsible to design all "techological" behaviors of the application. This layer reference Domain.
Presentation: It is the User Interface. Connects Domain and Dependency Injection layers. This layer can see Dependency Injection and Domain.
Dependency Injection: Solve the dependency problem. It returns an interface implementation passed by parameter. This layer can see Infrastructure and Domain.
As example shown below: (I am using C#)
Domain Level: As you can see, there are no actual implementation of the method. Only a dependency call finding an implementation for the interface IFight.
public class Samurai
{
public void Attack()
{
/*There are no class coupling here. 'Solve' receives an Interface as
parameter and do its job in order to return an object of the instance
and it calls the method Attack*/
Dependencies.Solver<IFight>().Attack(); //Forget about this right now. You will understand it as the post goes on.
}
}
Then we need to implement an interface to be implemented at infrastructure level.
public interface IFight
{
/*This interface is declared at the domain, altought, it is
implemented at infrastructure layer.*/
void Attack();
}
To make dependency injection works, it is need to implement it at domain level.
public class Dependencies
{
private static ISolve _solver;
public static ISolve Solver
{
get
{
if (_solver == null)
throw new SolverNotConfiguratedException();
return _solver;
}
set
{
_solver = value;
}
}
}
And also a Solver:
public interface ISolve
{
//This interface will be implemented at DependencyInjection layer.
T Solve<T>();
}
Infrastructure level:
Implementation of the interface
public class Fight : IFight
{
public void Attack()
{
Console.WriteLine("Attacking...");
}
}
Dependency Injection level:
Now it is important to set the injection
public class Solver : ISolve
{
private UnityContainer _container = new UnityContainer();
public Solver()
{
/* Using Unity "Framework to do Dependency Injection" it is possible do register a type.
When the method 'Solve' is called, the container looks for a implemented class that inherits
methods from a certain interface passed by parameter and returns an instantiated object.
*/
_container.RegisterType<IFight,Fight>();
}
//This is where the magic happens
public T Solve<T>()
{
return _container.Resolve<T>();
}
Explanation of the Dependency at Samurai Class:
//We are making a request of an interface implementation for Dependency
Solver. The Domain does not know who what class is doing it and how.
Dependencies.Solver<IFight>().Attack();
Presentation Level:
Samurai samurai = new Samurai()
samurai.Attack();
Conclusion:
We can see that domain is at the center of the implementation, and every business rule can be easily seen at that level whitout technical stuff being in the middle of it.
Upvotes: 0
Reputation: 13541
If you follow principles of onion architecture, then the domain is the middle layer (no dependencies) and infrastructure is the outer layer (has dependencies).
You don't want your domain model to be dependent on infrastructural concerns, so this means your base class definitely belongs to the domain layer. The idea is that any change in infrastructure (or any technical change for that matter) does not impact the domain/business/application layers.
Also, try to program against interfaces, for which the concrete implementation is injected at run time. This also avoids any coupling to infrastructural concerns in the middle layers.
Upvotes: 0
Reputation: 18034
Putting the base class for entities in the infrastructure layer is only a good idea if you have a layered architecture that puts infrastructure at the bottom - which is not what most architectures do nowadays.
So I'd recommend against this. Put the entity base type in the domain layer.
Nobody is going to ask "what domain concept is this?" if you name it appropriately. Make sure the class is abstract and properly documented. This will further clarify the situation.
With DDD, architectures that put the domain in the "center" (e.g. Hexagonal Architecture) are usually a better fit than classical layered architectures with infrastructure at the bottom. The important property of such architectures is that all dependencies point inwards, i.e. towards the domain.
Upvotes: 1
Reputation: 2893
It's called a layer supertype and is a common pattern.
In general, it's convenient to "hide" all infrastructure code that is required for your domain entities (such as database IDs needed by the persistence layer but not by the domain) in a common base class, such that the actual domain classes are not polluted by infrastructure code.
I agree that you should avoid circular dependencies. However, you don't need to actually move the base class to a separate project (to avoid circular dependencies). I guess what the authors mean is that semantically this base class belongs to the infrastructure layer since it contains database IDs.
Upvotes: 0