DDD architecture - c#

i have a this question, that i just cant get my head around it
Right now, i am implementing a DDD architecture, in a .NET CORE project, i have created 3 layers,
Application, Domain, Infrastructure, but there is a problem, on which i cant understand
I have implemented the Repository Patterns and IUnitOfWork, but a question remains in my head
The domain layer will do the business logic to the Data, but how is that Data going to be persisted in the DB? since the Domain layer cant have dependencies on infrastructure
Will it send the data back to the Application and then Application layer sends to the infrastructure? Or will the Domain layer have a ApplicationDbContext file too, like Infrastructure Layer?
Here is a snippet of my Current Folder structure!:

Domain Layer usually contains enterprise logic and entities. Application Layer would have Interfaces and types. The main difference is that The Domain Layer will have the types that are common to the entire enterprise, hence can be shared across other solutions as well. But the Application Layer has Application-specific types and interfaces.
The Core Layers (Domain and Application) will never depend on any other layer. Therefore we create interfaces in the Application Layer and these interfaces get implemented in the external layers. This is also known as the Dependency Inversion Principle.
The Infrastructure Layer is where you would want to add your Infrastructure. Infrastructure can be anything. Maybe an Entity Framework Core Layer for Accessing the DB including DB Contexts and Identity and etc. Most of the project's dependencies on external resources should be implemented in classes defined in the Infrastructure project. These classes should implement interfaces defined in the Application layer.
The Application layer has a dependency on the Domain layer and the Infrastructure layer has a dependency on both Application and Domain layers. In my approach which I usually apply CQRS pattern, I implement the handlers of my queries and commands in the Application layer.
In order to get a better understanding of this matter, I recommend you to study Clean Architecture articles on the web.

Related

Where repository classes should be?

When I try to use DDD with .NET and C# my usual procedure is to construct one project for the Domain Model, another one for Data Access and another one for the application itself, like ASP.NET Web API. Usually there are more projects involved, but these three I usually work with.
My point here is that in the Domain Model project I put all business rules. There I define the Domain types (entities, value types, aggregates and so forth) and the repository interfaces.
My point then is that after I define the repository interfaces I implement then in a separate project. That project is the Data Access project. My reason for that is that to implement the data access I usually need technologies which do so (like ADO.NET, EF, Dapper and others).
I myself find it bad form to couple those dependencies on the Domain project for some reasons. I like the Domain project to be self contained and decoupled from any technologies.
On the other hand, I've heard sometimes that repositories might contain business rules and should be implemented inside of the Domain project.
Which approach is right? My approach which decouples the repositories implementation from the domain project in order to avoid coupling dependencies on technologies to the domain project or the approach which allows business rules inside repositories and thus makes repositories live inside the Domain project?
Where repositories really should be? In the domain project together with the domain types or in a Data Access project?
Your approach is correct. Repositories should be implemented in infrastructure layer.
On the other hand, I've heard sometimes that repositories might contain business rules and should be implemented inside of the Domain project.
The only responsibility of a repository should be persistence. If you end up with business logic in repositories, you should refactor them. Move the business logic to the domain model and keep the repositories in the infrastructure.
If you have business logic in queries, an easy way to deal with it in C# is to return IQueryable<T> from repositories. Then you can use LINQ to create queries in application or domain services. Some might argue that it is a leaky abstraction - you limit the implementation of repositories to data access technologies that work well with IQueryable. The ease of use very often makes it worth a try.
Repositories are the boundary that mediates between the domain and the data mapper. I would say that repository isn't about data access but just who translate the domain into some kind of data using the data mapper and also it does the inverse translation from the data to domain.
Instead of defining and implementing them outside the domain projects, if you want to leave them as tech-agnostic, maybe you can define repository interfaces on the domain project and create a Domain.[SomeTech] where SomeTech may be EF, Dapper, and so on, and where you're going to implement tech-specific repositories.
Now your application project will need to reference both Domain and, for example, Domain.EF projects.
BTW, based on my own experience, a good separation of concerns in terms of how the code files are organized is less important than how the solution is architected in terms of software layers.
That is, if your project is entirely using an OR/M like Entity Framework, the chance that you change it in the future is insignificant, thus, don't waste your time creating a solution of too many projects with few classes each them and focus yourself on a good separation of concerns in your code.
There's always time to split your projects, while a wrong architecture is just a waste of time.
Keep in mind that every codebase, every project, every domain is different. There are no hard-and-fast rules. Design the code to best fit what works for your project.
I've heard sometimes that repositories might contain business rules
If that's the case then they're not merely repositories. In a strictest sense, a repository just persists things to some storage.
Now, there can be business-driven logic inside the repositories which is still just persistence logic. And it's possible that this persistence logic would, in the standard 3-layer setup you describe, need to be duplicated in any other implementation of that layer. That's not the end of the world.
But it does beg the question that you're asking. And, as I said, there really are no hard-and-fast rules. You would need to decide for your project which rules you want to maintain and design the code around those rules.
For example(s)...
You might move this "business logic" into the models or other domain code and keep the repositories simple.
You might keep this "business logic" in the repositories and re-implement it in other repository implementations.
You might create a thin layer between the traditional domain and the simple repositories which applies this "business logic". You can think of these as domain-owned wrappers to the repository interfaces. The sole purpose of these objects, which aren't really business models but are conceptual logical types related to the repositories, is to contain specifically this logic.
In the end, it's really up to you. There is no right answer except the answer which makes the most sense for your codebase and results in simple, maintainable code.
There should be a logical separation in your representation of the Solution [*1] between those objects representing data management, human interaction, system interaction, and your Problem Domain (problem object model).
Physical separation (into say Projects) is entirely optional. Many would argue that it is a good organizational practice.
Data management objects (e.g. repositories) should only have functionality to persist and retrieve persisted data, not business logic or rules.
[*1] Includes both objects that model your problem (the "Problem Domain"), as well as all the supporting objects required to produce a complete working system.

Where to put business (game) logic in aspnetboilerplate

I'm new to DDD (Domain Driven Design). In a traditional project I would generally make a persistence, business, and user interface layer. Now with aspnetboilerplate there is a core, application services, entityframework, and ui layer. My understanding is that the domain (core) layer is where my main business logic should be. What I'm trying to do is create a blackjack game using this architecture so that I can create a mobile and web app for it in the future. What I'm having a hard time figuring out where my methods dealing with dealer, cards, scoring etc, should be. My gut tells me it should be in the domain layer but I know that the application services layer is the intermediary between domain and presentation. The application services layer deals with Data Transfer Objects and what not. So What I'm trying to get at here is if my methods for how the game works should be in the domain layer or in the application services layer?
http://www.aspnetboilerplate.com/
The domain (core) layer is the correct place for your business logic. The application layer should be used for validation of the data transfer objects (DTOs) before passing data to the domain layer.
I am also had the same problems when I started using this framework. If you are trying to create a mobile and a web app, I recommend that you use the Application Layer(Service Layer) from Abp. Almost validations and exceptions are handled for you by the framework if you derive your DTOs from Abp's DTOs. The nice thing about the service layer form Abp is that it generates the Js Proxies to call these methods.
In the future, if you are trying to create a mobile App, you can just use the application layer from Abp template with Asp.NET Web Api. They will almost be a one to one map from your service layer to your Web Api.
To have a clear ideas about DDD please read the following article
Onion Architecture
It helped me a lot also stick to the documentation and have a look at
AspNetZero
It uses aspnet boilerplate

How to make the data access technology (Entity Framework) ignorance from the presentation layer (ASP.NET MVC)?

Premise:
I am exercising Domain-Driven Design and I separate my solution into 4 layers:
Presentation Layer
An ASP.NET Web API 2 project for a RESTful API web service
An ASP.NET Web MVC5 project for a documentation and admin screens
Application Layer
A class library project responsible to take commands from presentation layer and consume any domain services
Domain Layer
A class library project that contains business models and logic
A class library project that contains the domain services
Infrastructure Layer
A class library project that contains all the concrete implementation, like dataq persistance using Entity Framework, logging using Log4net, IoC using Simple Injector, etc
The domain layer only has a set of repository interfaces defined for the aggregates and it's up to the implementation data access mechanism which exists in the infrastructure layer to hide the implementation details.
In this exercise, I decide to use Entity Framework Database first approach. And of course, there is a app.config in the infrastructure project that contains a connection string.
Problems:
Ok, I spend a great deal and time trying to separate all the concerns and to focus on domain models. In the presentation layer (i.e., the API and MVC projects), there is no direct reference to the infrastructure project. And IoC container has been setup so all concrete implementation of the required interfaces would be injected into controller constructors.
When I select, for example, the API project as start project and run it, I got
An exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll but was not handled in user code.
Additional information: No connection string named 'xxxxxx' could be found in the application config file.
Question:
Now I understand if I install Entity Framework into the API project, copy and paste connection string from the app.config of the infrastructure project into the web.config of the API project, things will work. But that breaks our original purpose of separating concerns, doesn't it? If we do that, then what's the point of using Domain-Driven Design and making the data access technology ignorance from the presentation layer?
The reason we don't directly reference direct implementation of data access technology (i.e. concrete implementations that use dbContext and Linq) is that we could easily switch the underground access technology to something else.
So what would be the proper way to do it?!!
I do not want to install Entity Framework in my presentation layer, nor copy the connection string everywhere. I want all the data access and concrete implementation of repositories exist in just one library.
The Entity Framework configuration must be in the project where it is being used. This doesn't mean it's going to break your layered structure or your separation of concerns.
Remove all entityframework elements from your app.config. Create your own connection string element and provide it to entityframework on app startup.

Entities in shared layer (cross cutting concern) in a layered application?

In a layered application, is it good practice to have you entities defined in a shared layer? I figure that I will be using them across all layers. Or do they belong in the business layer?
MSDN's layered application guideline puts the business entities in the business layer
The Layered Architecture Sample for .NET puts the entities in the shared layer
Can it be like this?
Presentation
Business
Data
Shared
Entities
Or must it be like this
Presentation
Business
Entities
Data
Shared
What to do and why?
I usually organize projects in following structure:
Presentation (MVC application)
try to keep your controllers small as possible. Do not put any business logic into controllers. Relay on service interfaces instead concrete implementations. Use dependency injection.
Business layer
service classes belong here and they should contain all business logic
i group related services into folders by feature. Each service queries the DB with entity framework and maps the results into Model (a.k.a. View Models, Presentation Objects) objects. So the service layer does not return DB entities but return POCO classes.
shared folder contains services which are shared across multiple services (they are more like infrastructure code but i prefer to keep them inside the business/service project)
DAL data access layer
I prefer to use only entity framework without any other abstraction upon it. Some people use Repositories or implementing own unit of work pattern, but i do not recommend to do this. Entity framework is already implementing unit of work and encapsulating database selects with linq so there is no need for more abstraction.
this layer contains only Code First classes (entity framework entities)
I would say it depends if these entities contain business logic or not.
From the Layered Application Guidelines :
Business entities also validate the data contained within the entity
and encapsulate business logic to ensure consistency and to implement
business rules and behavior.
In contrast, the Layered Architecture Solution Guidance seems to rely on code generation to create Entities, they are mere data containers with little to no logic in them.
Rich domain entities tend to not be in a Shared module, since it would mean carrying around a ton of behavior that you don't want everyone to have (imagine being able to manipulate business logic directly on the client side...) Anemic ones on the contrary are lightweight and may be happily and conveniently distributed everywhere.
My approach is a little bit different. In data layer I store all my entities and in shared layer I have DTO object (Domain Transfer Objects) which are exact copy of entities but without Entity Framework control. To map each other, I'm using mapper (AutoMapper) which is fluent and easy to use.
I can't understand why Entity Framework doesn't support interfaces, using only instances.

Entity Data Framework and Web app architecture

I Am creating a web application and first use Entity Framework. I created Entity Data Model and now I am not sure, how to proceed now.
Premise: My database is really simple (Rating, WebPage, Visitor) and database tables corresponds to the business objects.
My suggestion is 3tier architecture but how to make it?
It is good idea create partial classes with the same name as Entity Framework objects (Rating, Visitor) and declare here new methods (GetAverageRating()...)? Or is better create some VisitorProvider, RatingProvider and place logic here?
It is better use EF objects in BLL and Presentation Layer or I should create my own BO objects on my BLL layer and transform EF object to BO?
I'm think, it is more practical use static methods on my DAL than instantiate classes on BLL. Do you agree?
Can you recommend me some best practices? I have many ideas how to create it, but I do not know what is the right.
3 layer architecture is quite popular but what it really means?
Presentation layer
Application layer
Database layer
If you ask what each layer means you can be pretty sure you will get several different answers. You can further divide each layer into sublayer and build layered hell like:
Client side presentation layer
Server side view layer
Controller layer
Service facade layer
Service layer
Domain objects layer
Repository + Factory layer
ORM layer
Stored procedure layer
Database view layer
Database table layer
WTF? That is just example that application can be easily over architected. It can go even worse if you insist that only neighbours can exchange data and if you decide to add special type of objects to be exchanged between layers instead of flowing sing set of objects through multiple layers.
Add layers which you need to make you more comfortable with developing the application and which will do reasonable separation of concerns and maintainability needed for the scale of your application. You can simply do the most simplest application which will be used just few weeks and must be developed as fast as possible. In such case you can do that within few days simply by using ASP.NET web forms and data source controls (or ASP.NET dynamic data). It can be badly extensible but in such situation it is exactly what you need to implement application quickly. Writing layers and doing all the stuff around maintainability and extensibility is reasonable if you need it. Another quick prototyping technique is ASP.NET MVC Scaffolding which can create quick multilayered skeleton of the application which can be further modified.
Both approaches are correct and it only depends on the approach you like. The first is called active record pattern but it is not used very often with entity framework. The second approach is more popular. You can either use EF directly in some middle class which you called Provider (common name is also Service). This class will do both data access logic and business logic. In more complex applications developers like to somehow wrap EF to separate class following repository pattern and call the repository either from service or directly from web app. code behind or controller (depending on amount of business logic). Try to do it without repository first. My personal opinion is that people should start to use repository only once they understand EF itself.
Again both approaches are correct. In a simple application it is fully acceptable to create EF model with POCO classes (EFv4.x) and use them in all layers. If you are using ASP.NET MVC you can find that you need special classes as view models to fully represent needs of your individual views. In a more complex application you can have separate objects exposed from a business layer - this is especially used if the business layer is exposed as a remote service (WCF).
It depends how you write these DAL methods - it is absolutely necessary to not share the EF context among requests! It also depends if you want to write some test or not. Layer defined by static methods is something which goes directly against testable architecture where you want unit test just single layer (unit testing with EF can be hard). It also depends if you want to use dependency injection which is based on instances.

Categories

Resources