DDD and data export system - domain-driven-design

I'm a beginner in DDD and am facing a little problem with architecture.
Our system must be able to export business data in various formats (Excel, Word, PDF and other more exotic formats).
In your opinion, which layer must be responsible for the overall process of retrieving source data, exporting them in the target format and preparing the final result to the user ? I'm confusing between domain and application responsibilities.
And regarding the export subsystem, should implementations and their common interface contract belong to the infrastructure layer ?

Neither Application nor Domain layer or any other 'layer'. DDD is not a layered architecture. Search for onion architecture or ports and adapters pattern for mor on this subject.
Now to the core of your problem. The issue you are facing is a separate bounded context and should go to a separate component of your system. Lets call it Reporting. And as it's just a presentation problem, no domain logic - DDD is not suitable for it. Just make some SQL views, read them using NHibernate, LINQ2SQL, EF or even plain DataReaders and build your Word/whatever documents using a Builder pattern. No Aggregates, Repositories, Services or any other DDD building blocks.
You may want to go a bit further and make all data presentation in your application to be handled by a separate component. Thats CQRS.

I usually take the simple approach where possible.
The domain code implements the language of your domain - The nouns, verbs etc.
Application code creates poetry using this language.
So in your example the construction of the output is an application concern, while the construction of the bits that the application will talk about (since you don't mention it) would the the domain concern.
e.g. if the report consists of sales data, that things like dates, bills, orders etc. would be abstractly constructed in the domain, while the application would concerned with producing documents using these.

Related

Using external API calls as a data source in domain-driven-design

I have a two-layer application which has the bottom layer for collecting data from external APIs and adding it to database and the second layer is for return data from database that is based on the data that I collected from the external API calls.
so I managed to put the external API calls in the infrastructure repositories with their interface in the domain.
So generally where I'm exactly stuck is to save this data that I'm collecting in database without creating a model for this data in the domain since this data is dependable on the external API I want to have this two layers totally separated collecting the data and return the other data without breaking the principles of domain-driven-design.
What I will try to answer here is how DDD could help and highlight that the import is an implementation detail after you applied some DDD principle to find a useful design and an appropriated implementation.
So you need data for your App/Bounded context which will have to generate statistics (if you can put more business language here DDD will be even more helpful). What is the business use of this app ? what are the languages (Ubiquitous Language) and boundaries (BC) ? How is it going to interop with others contexts (Context Mapping).
You will need implement this model, and here you could use the concepts defined and define a persistence model (potentially the language used in the API isn't the language used by your app) and also you might need some validations and business rules during the import of the data. Because you might define Aggregates that ensure the integrity of the system, well here I am speculating. But this is a scenario how I would applied DDD and to make the point that we cannot apply DDD to import. But import is potentially an implementation detail.

Understanding onion architecture

Onion Architecture Mockups
Above are two images that depict my understanding of Onion Architecture.
They are slightly different from the drawings found online, because they address an agenda that I cannot find an answer to.
Infrastructure, as far as I can tell, are things like persistence, logging, etc. I have written examples of them in italics. However, a lot of the time, infrastructure components, as well as UI, tend to need to communicate with one another. The UI might want to audit or log something, the persistence project may need to log something. Logging being one of the harder to fit items in onion architecture, my understanding is that a lot of people have different opinions on where you should and shouldn't log.
In my first drawing, I have put an Infrastructure Interfaces layer in the diagram to allow cross communication without any one component knowing the implementation of another component. This is something that I have seen in a few examples.
The second drawing is my preference, it uses a mediator to cross communicate between infrastructure, UI, and its basically a way to allow the core services to communicate with infrastructure indirectly (assume Service Interfaces is called Core Services on the right diagram). The logger would subscribe itself to certain events, as would the database etc.
The first diagram allows only pocos and interfaces in all layers except the outer layer (excluding the dependency resolver). The second allows domain and business logic in the core service layer and allow the infrastructure layers to do their jobs in isolation.
I justified the infrastructure components by ensuring that they had an output of some sort. Auditing and Logging would usually use a db of some sort, cache would usually store in memory and db should probably have been called persistence. However, there is a library called AutoMapper. I have seen it wrapped in some instances, so that its interface can go in the Core to be used in pretty much any infrastructure, but it seems like over abstraction to me. Automapper is kind of like the Events object in that all infrastructures use it to translate between itself and the domain, but I'm not sure if it fits in that layer since it is not a service.
Question: Which of the two is closest to the definition of onion architecture and where would you fit in a tool like auto mapper, and do you think trying to wrap something like that is over abstraction?
Thanks!
I've used Auto Mapper and the Onion Architecture. We configured AutoMapper in the MVC Global.asax file, that typically calls a Config Method in the AutoMapperConfig Class in the App Start directory.
Regarding your graphics, it appears one of them has a separate layer for the Mediator and Observer Patters. They're not necessarily needed but it entirely depends on your approach. Just as you can use Model-View-Controller Pattern in the Onion Architecture or Model-View-Presenter or Model-View-ViewModel. They're just coupling separate Patterns to incorporate some added benefit.
Here's where I first came across the Onion Architecture Jeffery Palermo. If you're wanting to a see a more pure graphical representation.

DDD and implementing persistence

I am getting my feet wet with DDD (in .Net) for the first time, as I am re-architecting some core components of a legacy enterprise application.
Something I want to clear up is, how do we implement persistence in a proper DDD architecture?
I realize that the domains themselves are persistence ignorant, and should be designed using the "ubiquitous language" and certainly not forced into the constraints of the DAC of the month or even the physical database.
Am I correct that the Repository Interfaces live within the Domain assembly, but the Respository Implementations exist within the persistence layer? The persistence layer contains a reference to the Domain layer, never vice versa?
Where are my actual repository methods (CRUD) being called from?
Am I correct that the Repository Interfaces live within the Domain
assembly, but the Repository Implementations exist within the
persistence layer? The persistence layer contains a reference to the
Domain layer, never vice versa?
Yes, this is a very good approach.
Where are my actual repository methods (CRUD) being called from?
It might be a good idea to not think in CRUD terms because it is too data-centric and may lead you into Generic Repository Trap. Repository helps to manage middle and the end of life for domain objects. Factories are often responsible for beginning. Keep in mind that when the object is restored from the database it is in its midlife stage from DDD perspective. This is how the code can look like:
// beginning
Customer preferredCustomer = CustomerFactory.CreatePreferred();
customersRepository.Add(preferredCustomer);
// middle life
IList<Customer> valuedCustomers = customersRepository.FindPrefered();
// end life
customersRepository.Archive(customer);
You can call this code directly from you application. It maybe worth downloading and looking at Evan's DDD Sample. Unit of Work pattern is usually employed to deal with transactions and abstracting your ORM of choice.
Check out what Steve Bohlen has to say on the subject. The code for the presentation can be found here.
I was at the presentation and found the information on how to model repositories good.
Am I correct that the Repository Interfaces live within the Domain
assembly, but the Repository Implementations exist within the
persistence layer? The persistence layer contains a reference to the
Domain layer, never vice versa?
I disagree here, let's say a system is comprised of the following layers:
Presentation Layer (win forms, web forms, asp.net MVC, WPF, php, qt, java, , ios, android, etc.)
Business Layer (sometimes called managers or services, logic goes here)
Resource Access Layer (manually or ORM)
Resource/Storage (RDBMS, NoSQL, etc.)
The assumption here is that the higher you are the more volatile the layer is (highest being presentation and lowest being resource/storage). It is because of this that you don't want the resource access layer referencing the business layer, it is the other way around! The business layer references the resource access layer, you call DOWN not UP!
You put the interfaces/contracts in their own assembly instead, they have no purpose in the business layer at all.

DDD vs N-Tier (3-Tier) Architecture

I have been practicing DDD for a while now with the 4 distinct layers: Domain, Presentation, Application, and Infrastructure. Recently, I introduced a friend of mine to the DDD concept and he thought it introduced an unnecessary layer of complexity (specifically targeting interfaces and IoC). Usually, its at this point, I explain the benefits of DDD-- especially, its modularity. All the heavy lifting and under the hood stuff is in the Infrastructure and if I wanted to completely change the underlying data-access method, I could do so with only having to touch the Infrastructure layer repository.
My friend's argument is that he could build a three tiered application in the same way:
Business
Data
Presentation
He would create business models (like domain models) and have the repositories in the Data layer return those Business models. Then he would call the business layer which called the data layer. I told him the problem with that approach is that it is not testable. Sure, you can write integration tests, but you can't write true unit tests. Can you see any other problems with his proposed 3-tiered approach (I know there is, because why would DDD exist otherwise?).
EDIT: He is not using IoC. Each layer in his example is dependent on one another.
I think you're comparing apples and oranges. Nothing about N-Tier prohibits it from utilizing interfaces & DI in order to be easily unit-tested. Likewise, DDD can be done with static classes and hard dependencies.
Furthermore, if he's implementing business objects and using Repositories, it sounds like he IS doing DDD, and you are quibbling over little more than semantics.
Are you sure the issue isn't simply over using DI/IoC or not?
I think you are mixing a few methodologies up. DDD is Domain-Driven Developement and is about making the business domain a part of your code. What you are describing sounds more like the Onion Architecture (link) versus a 'normal' 3-layered approach. There is nothing wrong with using a 3-layered architecture with DDD. DDD depends on TDD (TestDriven Developement). Interfaces help with TDD as it is easier to test each class in isolation. If you use Dependency Injection (and IoC) it is further mitigated.
The Onion Architecture is about making the Domain (a.k.a. business rules) independent of everything else - ie. it's the core of the application with everything depending on the business objects and rules while things related to infrastructure, UI and so on are in the outer layers. The idea is that the closer to the 'shell of the onion' a module is - the easier it is to exchange for a new implementation.
Hope this clears it a bit up - now with a minor edit!
Read "Fundamentals of Software Architecture: An Engineering Approach", Chapter 8, Page 100 to 107.
The top-level partitioning is of particular interest to architects because it defines the fundamental architecture style and way of partitioning code. It is one of the first decisions an architect must make. These two styles (DDD & Layered) represent different ways to top-level partition the architecture. So, you are not comparing apples and oranges here.
Architects using technical partitioning organize the components of the system by technical capabilities: presentation, business rules, persistence, and so on.
Domain partitioning, inspired by the Eric Evan book Domain-Driven Design, which is a modeling technique for decomposing complex software systems. In DDD, the architect identifies domains or workflows independent and decoupled from each other.
The domain partitioning (DDD) may use a persistence library and have a separate layer for business rules, but the top-level partitioning revolves around domains. Each component in the domain partitioning may have subcomponents, including layers, but the top-level partitioning focuses on domains, which better reflects the kinds of changes that most often occur on projects.
So you can implement layers on each component of DDD (your friend is doing the opposite, which is interesting and we might try that out as well).
However, please note that ("Fundamentals of Software Architecture: An Engineering Approach", Page 135)
The layered architecture is a technically partitioned architecture (as
opposed to a domain-partitioned architecture). Groups of components,
rather than being grouped by domain (such as customer), are grouped by
their technical role in the architecture (such as presentation or
business). As a result, any particular business domain is spread
throughout all of the layers of the architecture. For example, the
domain of “customer” is contained in the presentation layer, business
layer, rules layer, services layer, and database layer, making it
difficult to apply changes to that domain. As a result, a
domain-driven design approach does not work as well with the layered
architecture style.
Everything in architecture is a trade-off, which is why the famous answer to every architecture question in the universe is “it depends.” Being said that, the disadvantage with your friend's approach is, it has higher coupling at the data level. Moreover, it will creates difficulties in untangling the data relationships if the architects later want to migrate this architecture to a distributed system (ex. microservices).
N Tier or in this case 3-tier architecture is working great with unit tests .
All you have to do is IoC (inversion of control) using dependency injection and repository pattern .
The business layer can validate , and prepare the returned data for the presentation \ web api layer by returning the exact data which is required .
You can then use mock in you unit tests all the way through the layers.
All your business logic and needs can be on bl layer . And Dal layer will contain repositories injected from higher level.

best way to reference business objects from presentation layer..?

I want to develop an enterprise app that includes a WindowsForms presentation layer, middle-tier components for business logic and data access, and a MsSQL Server database. Middle-tier components should contain some business objects and will be called from presentation layer using .NET Remoting. Whitch is the best way (and why) to reference these business objects from presentation layer?
A) Create class library project, implementing business objects. Reference this project from presentation layer and middle-tier layer.
B) Create interface library project defining business objects. Create class library project implementing interfaces. Reference class library project from middle-tier layer. Reference interface library project from presentation layer.
C) Create separate class library projects for middle-tier and presentation layer. Reference corresponding project from presentation layer.
There's probably no clear cut and definite answer to this, it depends on what you are doing.
A will often be good enough in many cases. For small 'single app' projects there isn't really any reason why you can't just reference the business object library directly from both UI and BL layers. It's certainly the simplest, and sometimes simplicity is best.
B is probably the "best", You'll be abstracting your actual implementations away so future changes are possible without breaking contracts, and unit testing is easier if you have interfaces. The other advantage of this is that you won't find it too difficult to switch from B to C in the future if you find it necessary.
C is probably overkill in most cases. That said, on larger projects you may find it necessary. I've worked on large client-server n-tier applications that have had as many as three independent sets of data objects. One set used in the DA layer to map and store in the database. A second set in the business logic and network layers for processing and passing over the network, and the third set in the client for binding to the UI. It's worth considering using interfaces for C as well because of the abstraction advantages.
All in all, without knowing exactly your application domain or scope - B is a good starting point.
I've seen all three approaches work well.
What can sometimes be good is to start with A, then as the complexity increases move to B, then C.
In simple projects the "business objects" can be included in the same project as the presentation and persistence tiers - although it may seem heresy, defining the objects using different namespaces can provide enough separation between the "layers".
You may want to reconsider use of .NET Remoting - WCF is by far a better technology and much easier to use.

Resources