I've got some really expensive business logic inside my domain layer where the data must be tracked in order to get a picture of what happened if something fails. Because of this, I want to declare a simple logging interface:
public interface ILogger {
void Log(LogEntry entry);
}
Now my question is - where does this interface belongs to? Of course logging might be a infrastructure concern (and a little bit of cross layer concern), but if I place it in the infrastructure layer, my domain services don't get access to it. If I place it into the domain layer, I introduce the concept of logging into my domain, which feels awkward.
I'm already using certain concepts from CQRS & EventSourcing inside my application, however throwing a event for like everything that happens with the data inside a domain service seems like an overkill (especially if the data falls into a state that doesn't get returned by a domain service until further transformations have been made.)
There are some options here.
Use decorators. You say you are already using CQRS, so add decorators to the commands/queries which you want to log. The downside is that you can only log before and after the execution of the command/query, not during the execution. And I'm not sure if it will be easy to log for your events as well this way.
Use your interface. If you choose this path, than indeed your ILogger interface should be in the domain layer, because the domain will require a component that implements your logger requirements, so the domain layer is the one to define this interface. The implementation of it must be elsewhere, and in an infrastructure layer sounds fine to me.
[...] my domain services don't get access to it
Why not? ILogger should live in the infrastucture layer, but who said that domain layer has no access to infrastructure members?
As far as I know, infrastructure is an unrelated non-domain specific code which solves common problems like I/O, networking, database-access and so on. And logging is an infrastructure concern.
Infrastructure code should implement or provide cross-layer software pieces, and it might provide a infrastructure-based ILogger implementation. If your domain requires some kind of specific code for logging, you'll provide a SomeDomainLogger implemented in the domain layer.
I don't know if you're already using inversion of control, since this is the best way to load such kind of implementations of infrastructure code.
Related
From what I understand in onion architecture, the domain must contain all the business logic. And enforcing database validations are typically done by using Services.
My code is inspired from this repo https://github.com/asadsahi/AspNetCoreSpa , where they are using features, where each folder has all the validation rules and logic for specific feature inside the application layer.
What is the best way to share a specific validation for multiple features? Should I create a service and use it for each feature?
And what is the reason that they moved all the business logic to the application layer while the domain entities does not have any logic?
I found a good article talking about what I need here Dealing with Duplication in MediatR Handlers
Excluding sub-handlers or delegating handlers, where should my logic
go? Several options are now available to me:
Its own class (named appropriately) Domain service (as was its
original purpose in the DDD book) Base handler class Extension method
Method on my DbContext Method on my aggregate root/entity As to which
one is most appropriate, it naturally depends on what the duplicated
code is actually doing. Common query? Method on the DbContext or an
extension method to IQueryable or DbSet. Domain behavior? Method on
your domain model or perhaps a domain service. There’s a lot of
options here, it really just depends on what’s duplicated and where
those duplications lie. If the duplication is within a feature
folder, a base handler class for that feature folder would be a good
idea.
In the end, I don’t really prefer any approach to the another. There
are tradeoffs with any approach, and I try as much as possible to let
the nature of the duplication to guide me to the correct solution.
Sorry for my English, I am writing a real estate appraisal module and decided to try writing in the DDD paradigm.
I looked at examples and different articles and formed the following picture for myself (simplified):
ApplicationCore.Domain - the core of business logic, contains all the necessary objects divided into 2 typesа
Entitys - if an entity needs to be stored in a database and it is a ready-made complete business logic object.
ValueObjects - all other properties that encapsulate the behavior, are compared by the value of the fields, and are part of Entity
It is very important to create only valid objects, so I create everything through factories with a validator, and the constructors are private.
There should be no references to other dependencies, as isolated as possible.
ApplicationCore.App - a layer above ApplicationCore.Domain, contains a link to it.
works with objects from ApplicationCore.Domain and uses external services through Port/Adapter.
Port - For example, an abstraction of a repository, its implementation through an Adapter on the Infrastructure layer.
interaction logic for ApplicationCore is in AppServices - for classic implementation or in Command / Request - for CQRS
Infrastructure - contains a link to ApplicationCore.Domain and ApplicationCore.App.
Implements the ports of the ApplicationCore.App layer
Entities are independent from each other and refer to each other by keys for interaction.
I kept the basic logic of the assessment system in this paradigm.
But here it was necessary to add a service that receives additional information for evaluation from different sources, while in wiretapping mode.
Those. Works against the background of listening to TcpIp socket
Service settings are stored in the database and change frequently - i.e. you need to introduce a new Entity
A chain is formed
DataProvider (ApplicationCore.Domain) -> IDataProviderRepository (ApplicationCore.App) -> EfDataProviderRepository (Infrastructure).
DataProvider - must depend on ITcpIpTransport, without it it is just a set of settings for TcpIpTransport.
Logically, DataProvider is a service for receiving data, but it has settings and state stored in the database, i.e. you need to make it Entity.
If you make the DataProvider dependent on the Infrastructure layer, then ApplicationCore.Domain will also have ports to external services, is this permissible?
how best to implement it.
I've to admit that is a bit hard to understand everything. Especially at the end, you speak about object that isn't clear where they are and what they do.
Anyway, you cannot use anything for the layer above (infrastructure) into the layers below (application and domain). I don't know how would you do it, but as a simple dependency it would not leave you compile any project. You'll end with a circular dependency.
Given that you would not do this, you can build a service (I do it with static functions to avoid any kind of unwanted implementation) into the domain layer. That service use interfaces that are implemented into the application layer. Into the application layer you'll also use (or reuse) interfaces that will be implemented into the infrastructure layer.
Should domain services inject other domain services and do work between each other and have the commandhandler be dumb. OR, should the domain services be dumb (only be used to interface the repository barrier) and the majority of work be done in commandhandler's? What is best practices here...
I would say add ALL business logic inside domain objects (and also domain services if the functionality doesn't fit into an object) and use commandhandlers for things like:
instantiate domain objects and run methods on them,
run methods on domain services,
provide dependencies to domain objects,
manage database transactions,
...
You can check out the onion architecture, I guess your domainservices are inside Domain Model and commandhandlers inside Application Services.
CommandHandlers could be viewed as the use case's of your application, therefore it is their function to orchestrate the access to repositories, domain services and domain models.
If you start to inject domain services inside each other you start to couple them and lose the single responsibility of each one.
My answer is to let the commandHandler deal with the execution of the domains services and models needed in your use case, this way you can freely compose any new command without having to deal with domain services that are full of logic that belongs to a use case, and not entirely to the domain itself.
If your 1 service is dependent on other service ,that means you have made some design error . If this the case the just move the code that you want share is some other shared class library so that both services can use it with out any dependency on each other
I would not recommend pouring all the logic in command handler, many parts of the domain could not be set from out of the domain class so I would suggest only write work follow and business logic (not core ) in command handler
I am currently studying the domain driven design, and try to apply it for a WPF project. I watched some tutorial videos, and read many articles, like :
Onion archicecture dependencies in the same layer: Infrastructure and Web communicating
http://eohmicrosoft.blogspot.fr/2012/08/laying-it-out-onion-architecture.html
Domain Driven Design: Domain Service, Application Service
I understood the focus on interfaces and inversion of control. I read there were some recurrent layer names (domain/core for the representation of the sphere of knowledge, infrastructures for persistance, application for ... i don't understand), but they change, depending of articles I read. Some even do not appear.
Would it be possible to have an list of all layers that, in theory, are required in an onion architecture to face all needs and problems, with their intent (what kind of code do they contain, what kind of need do they try to fulfill, which layer do they need to reference), please ?
Just some personal experience, I use this architecture mentioned in Eric Even's DDD book:
In short:
1) Interfaces is consist of components that are responsible for interacting with user(a real endpoint user or a remote machine), web mvc controller, web view object, remote facade for example.
2) Application defines what features your system provide. I think it's highly coupled with the Interfaces layer. If you define a method in Application, often you need to add a Interfaces class/method as well. But several Interfaces class/method may depends on the same Application object, you provide both a web ui and a web service for place order, for example.
3) Domain, the most stable part of your system. For example, in language context, word/sentence are Domain objects that have their own meaning, I oganized them to form this answer. So you could consider me as an Application object although not a good one 'cause I don't speak fluent English :P
4) Infrstructure, actually I don't think this is a layer, it implements all the above three. For example, you have an interface OrderRepository in your domain layer and you could implement it using some orm framework (persistence infrastructure). Most of my infrastructure objects are adapters (implements an interface in Application/Domain/Interfaces layer and adapt to external components like database, messaging provider, mail server and so on).
Hope this helps.
Update for infrastructure intent:
This is one of our project's package view.
There are some adapters in the infrastructure layer:
1.infrastructure.channel.XXX each package contains several adapters to a particular online payment provider.
2.infrastructure.payment contains adapters to a payment system of our organization but it is in another bounded context. We use MakePaymentService (a domain service) to decouple the payment system from other part of this system.
3.infrastructure.messaging contains adapters to messaging provider, we provide a jms implement for PaymentWasMadeNotifier (an application service)
4.infrastructure.persistence contains adapters to database, we provide a iBATIS(a orm framework in Java) for Domain Repositories.
These above adapters all implements some interface s in Application/Domain layers.
Below is some "service", but they are generic:
5.infrastructure.mail
6.infrastructure.logging
7.infrastructure.security
These package above expose some interface and implementations. For example, we provide a MailManager interface, it's agnositic to particular features. The subject, content is up to the application layer/domain layer. We provide an implementation using javamail in the same package.
public interface MailManager {
void send(String subject, String content);
}
8.infrastructure.time this one is special, we have some cron job in this system, so we introduce a Clock to decouple the time from job setting and therefore its friendly to tests (Just imagine that we have a job, it should be launched at 25th, every month, we can test the job by setting current time to 25th, even if it's 1st today). We provide an implementation in persistence package(For some reasons, we need to use database' time in production)
public interface Clock {
Date now();
}
So my understanding is: infrastructure provides service/implementations to your other three layers, but they are technology specific. For example, Subject, content, from, to, cc are domain models in mailing context, but they are infrastructures in your domain context. The infrastructure layer separate them for you.
Totally agree with Hippoom's answer. It is perfect to start from there.
Now,
I read there were some recurrent layer names (domain/core for the
representation of the sphere of knowledge, infrastructures for
persistance, application for ... i don't understand), but they change,
depending of articles I read. Some even do not appear.
Yes, decision about layers in an application depends upon many factors in a particular scenario. It is like how a universities divide their programs and make curriculum. It depend upon the capacity/diversity they want to serve, the need in hand and the purpose of university. It is very different in details (naming and partitions) across the globe but the core and intent is always same.
In the same way, Layers in an application depends upon the need and scope. Sometime architects used to define the name of layers as per their philosophy and convention followed in the organization. So sometime the intent and name may differ to some extent. But the code idea of having salable, maintainable and fulfilling the functional and non-functional requirements in hand, remains always same.
Would it be possible to have an list of all layers that, in theory,
are required in an onion architecture to face all needs and problems,
with their intent (what kind of code do they contain, what kind of
need do they try to fulfill, which layer do they need to reference),
please ?
Hippoom did it very well already and he described the intent in shot also.
Standard Layers are described here: http://jeffreypalermo.com/blog/the-onion-architecture-part-1/
As I already mentioned layers may differ as per applications need.
Hope it would help you. Thanks.
Included details as per David's first comment below:
Application services implement the use cases and make calls to the Domain Services and Domain Entities and Infrastructure Services in order to get the job done. It provides interfaces to outside world (mainly UI layer projects) to accomplish certain functionalities. For example, UserService is an application service. UserService may provide functionalities to check for authentication for user and authorization for particular resource, change privilege for a user by admin, ban the user etc. To accomplish these use cases, it would use UserRepository and UserEntity from lower layers.
Domain services are application-agnostic; they provide a means to ensure the integrity of the domain model by encapsulating CRUD (Create, Read, Update, Delete) operations and data access. They usually have Repositories of Domain objects and UoW implementation etc in Onion Architecture.
I have an application that will have some presentations layer (web, mobile, wpf, wcf, windows service to work on background etc...) and We are using NHibernate to persist the domain objects. We will have repositories (class library) to persist data, a service layer to use theses repositories to persist according to business rules. My question is, we do not know how to implement the a trasactional management in this service layer. We will probably use (more than one) repositories in a same service layer method and we need to control the transaction on the service layer. I would like to implement something like this (by attributes):
public class DomainObjectService
{
[Transactional]
public bool CreateDomainObject(DomainObject domainObject, /* other parameters */)
{
foreach(var item in /* collection */)
{
_itemRepository.Save(item);
}
if (/* some condition */) {
/* change the domainObject here */
}
_domainObjectRepository.Save(domainObject);
}
}
And does this Transactional attribute control my transactional with Commit/RollBack when we got erros. Is it possible? Or is there another solution to do this?
Thank you
What you have asked does not have a straight forward answer.
The behavior you wish to have sounds like you need to implement a unit of work pattern.
NHibernate's own ISession is in fact an implementation of a unit of work. I personally recommend implementing your own unit of work so that you have greater control over what your specific application considers a unit of work.
The use of attributes in a service layer class really doesn't make a lot of sense to me personally. I have seen people create custom controller attributes in an MVC application that handles transactions but I've never personally agreed with that kind of implementation.
You mentioned using more than one repository in the service layer. This is quite a common practice but it also means that each of those repositories will need to be operating within the same unit of work. If you application is using dependency injection, then one option is to have each repository accept an ISession in its constructor. Your dependency injection framework of choice could be setup in such a way as to inject the same ISession into all of the repositories. Your setup could be configured to begin a new transaction every time a new ISession is created.
You also mentioned different presentation layers such as web, mobile, wpf, etc. How you deal with sessions and transactions in each of those different types of applications can be quite different. That is why I always point people in the unit of work direction because each of those different application types could have a completely different definition for what it considers a unit of work. For a web application, you would typically go with a new unit of work for each web request. For a wpf application, the unit of work could be per screen, or until the user hits the save button, etc. Also, by implementing a unit of work, you can reuse that same unit of work implementation more easily across those different application types.
Again, this is not a question wish a straight forward answer but in general, I typically make use of a custom unit of work and a dependency injection framework to make this problem much easier to deal with.
Here are some helpful links that you may wish to investigate:
http://nhibernate.info/doc/patternsandpractices/nhibernate-and-the-unit-of-work-pattern.html
Correct use of the NHibernate Unit Of Work pattern and Ninject
Unit of work/repository managers for NHibernate?