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.
Related
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.
My company is trying to adopt DDD. It seems the DDD's guidance is to require the domain assembly to define all of its service interfaces and allow implementors to take a reference on the domain assembly and implement the service interfaces. Then using DI the domain will get the implementations. However, for cross cutting concerns, it seems irresponsible to require the domain assembly to re-define interfaces for things like logging, etc which are not the core business domain of that assembly. I've noted that a number of commercial components like Quartz.NET are using a standard, widely acceptable set of interfaces like Apache Commons to solve the cross cutting concerns in a framework friendly way. Is this consistent with DDD way or does one really have jump through hoops like AOP, and redefining the same interfaces for cross cutting concerns and then using an adapter pattern?
For reference:
From http://www.infoq.com/articles/ddd-in-practice
"These are reusable non-domain related concerns that typically tend to be scattered and duplicated all over the code including the domain layer. Embedding this logic in the domain objects leads to tangling and cluttering of the domain layer with non-domain related code."
From http://cyrille.martraire.com/2009/12/your-crosscuttingconcerns-are-someone-else-core-domai/
"Your cross-cutting concerns are someone else core domain"
It seems the DDD's guidance is to require the domain assembly
DDD doesn't require anything. A domain layer groups domain concepts and use cases. The abstractions defined at the Domain level are needed by the domain itself. And I mean needed by the domain use cases. Logging is an infrastructural (technical) aspect. Usually such abstractions are part of a common, shared layer/component and are usable by all the parts of the app.
The Domain doesn't care about this stuff and DDD shouldn't be considered a recipe, a 'how to'. It's a mindset where the design of the app revolves around business concepts and use cases, all other technical aspects are implementation details.
"Your cross-cutting concerns are someone else core domain"
This means the functionality that is simply a support system for you, it's the purpose (the domain) of other component.
I'd advise you too read way more about DDD and to try to grok the mindset and to employ a use-case approach for your app. Think of your app as a group of many specialized mini-apps, each with their very own concerns but which have to communicate with others. If you built things component by component, then you've understood DDD and incidentally you're also practicing Agile.
Ultimately it's up to you. But consider that standards do change. Things are not alway long lived in our industry, and shielding yourself from unanticipated and costly change is generally a good idea. You have to make a judgement call here. Do you want to adopt someone else's interface and be beholden to it, or define your own. Even if you do adopt the interface, you are not forced to move on from it, but the implementations may change forcing you to write an adapter at a later date. As long as you are coding to an interface and not an implementation, you already better off.
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.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I've received the go-ahead to start building the foundation for a new architecture for our code base at my company. The impetus for this initiative is the fact that:
Our code base is over ten years old and is finally breaking at the seams as we try to scale.
The top "layers", if you want to call them such, are a mess of classic ASP and .NET.
Our database is filled with a bunch of unholy stored procs which contain thousands of lines of business logic and validation.
Prior developers created "clever" solutions that are non-extensible, non-reusable, and exhibit very obvious anti-patterns; these need to be deprecated in short order.
I've been referencing the MS Patterns and Practices Architecture Guide quite heavily as I work toward an initial design, but I still have some lingering questions before I commit to anything. Before I get into the questions, here is what I have so far for the architecture:
(High-level)
(Business and Data layers in depth)
The diagrams basically show how I intend to break apart each layer into multiple assemblies. So in this candidate architecture, we'd have eleven assemblies, not including the top-most layers.
Here's the breakdown, with a description of each assembly:
Company.Project.Common.OperationalManagement : Contains components which implement exception handling policies, logging, performance counters, configuration, and tracing.
Company.Project.Common.Security : Contains components which perform authentication, authorization, and validation.
Company.Project.Common.Communication : Contains components which may be used to communicate with other services and applications (basically a bunch of reusable WCF clients).
Company.Project.Business.Interfaces : Contains the interfaces and abstract classes which are used to interact with the business layer from high-level layers.
Company.Project.Business.Workflows : Contains components and logic related to the creation and maintenance of business workflows.
Company.Project.Business.Components : Contains components which encapsulate business rules and validation.
Company.Project.Business.Entities : Contains data objects that are representative of business entities at a high-level. Some of these may be unique, some may be composites formed from more granular data entities from the data layer.
Company.Project.Data.Interfaces : Contains the interfaces and abstract classes which are used to interact with the data access layer in a repository style.
Company.Project.Data.ServiceGateways : Contains service clients and components which are used to call out to and fetch data from external systems.
Company.Project.Data.Components : Contains components which are used to communicate with a database.
Company.Project.Data.Entities : Contains much more granular entities which represent business data at a low level, suitable for persisting to a database or other data source in a transactional manner.
My intent is that this should be a strict-layered design (a layer may only communicate with the layer directly below it) and the modular break-down of the layers should promote high cohesion and loose coupling. But I still have some concerns. Here are my questions, which I feel are objective enough that they are suitable here on SO...
Are my naming conventions for each module and its respective assembly following standard conventions, or is there a different way I should be going about this?
Is it beneficial to break apart the business and data layers into multiple assemblies?
Is it beneficial to have the interfaces and abstract classes for each layer in their own assemblies?
MOST IMPORTANTLY - Is it beneficial to have an "Entities" assembly for both the business and data layers? My concern here is that if you include the classes that will be generated by LINQ to SQL inside the data access components, then a given entity will be represented in three different places in the code base. Obviously tools like AutoMapper may be able to help, but I'm still not 100%. The reason that I have them broken apart like this is to A - Enforce a strict-layered architecture and B - Promote a looser coupling between layers and minimize breakage when changes to the business domain behind each entity occur. However, I'd like to get some guidance from people who are much more seasoned in architecture than I am.
If you could answer my questions or point me in the right direction I'd be most grateful. Thanks.
EDIT:
Wanted to include some additional details that seem to be more pertinent after reading Baboon's answer. The database tables are also an unholy mess and are quasi-relational, at best. However, I'm not allowed to fully rearchitect the database and do a data clean-up: the furthest down to the core I can go is to create new stored procs and start deprecating the old ones. That's why I'm leaning toward having entities defined explicitly in the data layer--to try to use the classes generated by LINQ to SQL (or any other ORM) as data entities just doesn't seem feasible.
I would disagree with this standard layered architecture in favor of a onion architecture.
According to that, I can give a try at your questions:
1. Are my naming conventions for each module and its respective assembly following standard conventions, or is there a different way I
should be going about this?
Yes, I would agree that it is not a bad convention, and pretty much standard.
2. Is it beneficial to break apart the business and data layers into multiple assemblies?
Yes, but I rather have one assembly called Domain (usually Core.Domain) and other one called Data (Core.Data). Domain assembly contains all the entities (as per domain-driven-design) along with repository interfaces, services, factories etc... Data assembly references the Domain and implements concrete repositories, with an ORM.
3. Is it beneficial to have the interfaces and abstract classes for each layer in their own assemblies?
Depending on various reasons. In the answer to the previous question, I've mentioned separating interfaces for repositories into the Domain, and concrete repositories in Data assembly. This gives you clean Domain without any "pollution" from any specific data or any other technology. Generally, I base my code by thinking on a TDD-oriented level, extracting all dependencies from classes making them more usable, following the SRP principle, and thinking what can go wrong when other people on the team use the architecture :) For example, one big advantage of separating into assemblies is that you control your references and clearly state "no data-access code in domain!".
4. Is it beneficial to have an "Entities" assembly for both the business and data layers?
I would disagree, and say no. You should have your core entities, and map them to the database through an ORM. If you have complex presentation logic, you can have something like ViewModel objects, which are basically entities dumbed down just with data suited for representation in the UI. If you have something like a network in-between, you can have special DTO objects as well, to minimize network calls. But, I think having data and separate business entities just complicates the matter.
One thing as well to add here, if you are starting a new architecture, and you are talking about an application that already exists for 10 years, you should consider better ORM tools from LINQ-to-SQL, either Entity Framework or NHibernate (I opt for NHibernate in my opinion).
I would also add that answering to as many question as there are in one application architecture is hard, so try posting your questions separately and more specifically. For each of the parts of architecture (UI, service layers, domain, security and other cross-concerns) you could have multiple-page discussions. Also, remember not to over-architecture your solutions, and with that complicating things even more then needed!
I actually just started the same thing, so hopefully this will help or at least generate more comments and even help for myself :)
1. Are my naming conventions for each module and its respective assembly following standard conventions, or is there a different way I should be going about this?
According to MSDN Names of Namespaces, this seems to be ok. They lay it out as:
<Company>.(<Product>|<Technology>)[.<Feature>][.<Subnamespace>]
For example, Microsoft.WindowsMobile.DirectX.
2.Is it beneficial to break apart the business and data layers into multiple assemblies?
I definitely think its beneficial to break apart the business and data layers into multiple assemblies. However, in my solution, I've create just two assemblies (DataLayer and BusinessLayer). The other details like Interfaces, Workflows, etc I would create directories for under each assembly. I dont think you need to split them up at that level.
3.Is it beneficial to have the interfaces and abstract classes for each layer in their own assemblies?
Kind of goes along with the above comments.
4.Is it beneficial to have an "Entities" assembly for both the business and data layers?
Yes. I would say that your data entities might not map directly to what your business model will be. When storing the data to a database or other medium, you might need to change things around to have it play nice. The entities that you expose to your service layer should be useable for the UI. The entities you use for you Data Access Layer should be useable for you storage medium. AutoMapper is definitely your friend and can help with mapping as you mentioned. So this is how it shapes up:
(source: microsoft.com)
1) The naming is absolutely fine, just as SwDevMan81 stated.
2) Absolutely, If WCF gets outdated in a few years, you'll only have to change your DAL.
3) The rule of thumb is to ask yourself this simple question: "Can I think of a case where I will make smart use of this?".
When talking about your WCF contracts, yes, definitely put those in a separate assembly: it is key to a good WCF design (I'll go into more details).
When talking about an interface defined in AssemblyA, and is implemented in AssemblyB, then the properties/methods described in those interfaces are used in AssemblyC, you are fine as long as every class defined in AssemblyB is used in C through an interface. Otherwise, you'll have to reference both A, and B: you lose.
4) The only reason I can think of to actually move around 3 times the same looking object, is bad design: the database relations were poorly crafted, and thus you have to tweak the objects that come out to have something you can work with.
If you redo the architecture, you can have another assembly, used in pretty much every project, called "Entities" that holds the data objects. By every project i meant WCF as well.
On a side note, I would add that the WCF service should be split into 3 assemblies: the ServiceContracts, the Service itself, and the Entities we talked about. I had a good video on that last point, but it's at work, i'll link it tomorow!
HTH,
bab.
EDIT: here is the video.
I am a asp.net developer and don't know much about patterns and architecture. I will very thankful if you can please guide me here.
In my web applications I use 4 layers.
Web site project (having web forms + code behind cs files, user controls + code behind cs files, master pages + code behind cs files)
CustomTypesLayer a class library (having custom types, enumerations, DTOs, constructors, get, set and validations)
BusinessLogicLayer a class library (having all business logic, rules and all calls to DAL functions)
DataAccessLayer a class library( having just classes communicating to database.)
-My user interface just calls BusinessLogicLayer. BusinessLogicLayer do proecessign in it self and for data it calls DataAccessLayer functions.
-Web forms do not calls directly DAL.
-CustomTypesLayer is shared by all layers.
Please guide me is this approach a pattern ? I though it may be MVC or MVP but pages have there code behind files as well which are confusing me.
If it is no pattern is it near to some pattern ?
That's not four layers, that's three layers, so it's a regular three tier architecture.
The CustomTypesLayer is not a layer at all. If it was, the user interface would only use the custom types layer and never talk to the business layer directly, and the data access layer would never use the custom types layer.
The three tier architecture is a Multitier architecture
As far as patterns go, I recommend getting to grips with these:
My biggets favourite by a mile is the Dependency Inversion Principle (DIP), also commonly known as (or at least very similar to) Inversion of control (IoC) ans Dependencey Injection; they are quite popular so you should have no problem finding out more info - getting examples. It's really good for abstracting out data access implementations behind interfaces.
Lazy Load is also useful. Interestingly, sometimes you actually might want to do the opposite - get all the data you need in one big bang.
Factory pattern is a very well known one - for good reason.
Facade pattern has also helped me keep out of trouble.
Wikipedia has a pretty good list of Software design patterns, assuming you haven't seen it yet.
A final thing to keep in mind is that there are three basic types of patterns (plus a fourth category for multi-threaded / concurrency); it can help just to know about these categories and to bear them in mind when you're doing something of that nature, they are:
Creational
Structural
Behavioral
Take a look at the Entity Framework or LinqToSQL. They can both generate your data access layer automatically from your database. This will save you a lot of (boring) work and allow you to concentrate on the interesting layers.
Code-behind does not really have anything to do with architecture - it is more of a coding style. It is a way of separating logic from presentation. Any architecture you mention can be used with or without code-behind.
You seem to be describing a standard three-tier architecture. MVC is a pattern than describes how your layers and the user interact. The user requests a page (represented by a View), which requests its data from the Controller. The Controller communicates with your business layer (Model) to extract the correct data and passes it to your View for display. If the View is interactive, for instance it allows the user to update something, then this user action action is passed back to your Controller, which would call the relevant method against the business layer to save the update to the database.
Hope this helps.