Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
Can someone explain?
I'm trying to convert my wpf app mvvm into different layers (reading ddd). I have some small confusions
Presentation Layer (WPF, WEB, API) (ok.. this I know )
Entity Model (I know is the class that represent database table e.g
customer {id,name,surname,phone} from Entity Framework
but the following confuse me
Domain model (is the class that represent sql table columns? e.g
customer {Id,Name,Surname,phone} or the class that make sense for my
application e.g Customer {ID,FullName,Balance}
Where domain model lives? in which layer (seperate dll ?, in service
layer ? or in data repository dll)
DTO (Data Transfered object) is it the same as domain model?
Service Layer (is it a separate dll?)
Business Layer (many times i see the word business layer, some
refer it as service layer) what is it actually? is it the same? is it
a different class? a different dll (layer) that has it's own
responsibility apart from service layer?
Data Repository (question is, if service layer or business layer should be implement in the same layer that repository lives)
with all the above i have make sample application trying to understand where each one goes.
STEPS I FOLLOW
I have sucesfully understant the data repository. a simple interface
with CRUD and or complex queryies
I create a IService that implements and inherited from reposiroty
Now in wpf i have to reference the service dll, but wpf needs not only service dll but also repository dll because service layer is using it.
My Question on this is. Is It normal? shouldn't service be independent?
Should Service Layer used it's own models? and convert data repository models to service models? therefor wpf will not need reference to repository? ( but if so.. isn't duplicate work?)
Domain model
It depends on which pattern you want implement: rich domain model or anemic.
Some refs:
DDD vs Anemic domain models
Anemic domain model
Rich vs anemic domain model
In two words:
rich domain model - it's a model, when business logic incapsulated at your business object (model).
anemic domain model - it's a model, when business logic implemented at service layer.
If you talks about services, it's not pure DDD, it's anemic.
Fowler told that anemic is an anti-pattern, but it's used a quite often. The main problem of rich domain model, that you need a lot of experience to realise right way to implement it.
I think in your case you can use entities as domain objects.
Where domain model lives?
If you trying to implement domain model, it requires a organised structure of you solution.
Usually it contains next projects:
*.Domain - for domain objects
*.Application - for you business logic, if we talk about anemic model
*.Dto or *.Contract - for dto's or another objects that can be use at outer scope of your application (for services interactions, dto's, etc.)
*.Persistence - for data layer
Dto(Contract) is placed in another project in case reusing items implemented at them.
Where * is your project name.
DTO
Dto depends on your needs.
I recommend declare dto's for each purpose, but if you don't want, you still can return domain object (but some people can say, that it's bad practice).
As I told previously you can place dto's to *.Dto or *.Contract projects
Service Layer and Business Layer
Implement at your *.Application
Data Repository
Usually you prefer to declare Data Repository interfaces at *.Domain or *.Application and implementation at *.Persistence. It allows you use interfaces and don't care about realisation.
Is it normal? shouldn't service be independent?
Best practice it's when service depends just on your *.Domain assembly.
Should Service Layer used it's own models? and convert data repository models to service models? therefor wpf will not need reference to repository? ( but if so.. isn't duplicate work?)
You services should work with domain models, and return dto's when it needs. One of general ideas of ddd, that you have common model for all operations. So it's good if you can return your domain model from repository.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I used to deal with simple apps that have Service Layer containing all of the business logic. In Domain Driven Design it's common to keep business logic in a rich model.
Watched a tutorial by Pluralsight in which they mention Repositories and noticed that a repo normally contains basic CRUD operations (create, update, fetch & remove entity). Nothing much was explained with regard to Entity Framework.
Entity Framework 6 & Entity Framework Core already provide Repository/UoW out of the box. I'm wondering if we can omit creating Repository Layer in this case?
So, how I imagine the app without a separate Repository layer...
My understanding is:
For example we have Customer model as an Aggregate Root (rich domain model). And that model has one-to-many relation ICollection<Payment> Payments. Plus, according to DDD - we keep our logic inside the model - so we have MakePayment method.
The code will be as follows:
public class Customer
{
public virtual ICollection<Payment> Payments { get; set; }
// ... other properties/collections
public void MakePayment(decimal amount)
{
this.Payments.Add(new Payment() { Amount = amount });
}
}
With Entity Framework we can eagerly load the entire tree with the result Customer already has all their Payments mapped.
(say, we deal with an ASP.NET WebAPI app)
So, in order to make a payment, I imagine, we do the following:
in our controller / service we fetch a customer (for example by id)
then follows the code customer.MakePayment(10);
after that we call dbContext.SaveChanges() method
DbContext tracks the changes and stores the payment - Bingo!
Is my understanding correct?
Regarding Service Layer:
Would it be okay to have Service Layer with DDD in such a web app?
I still think keeping the code in controller isn't necessarily the right thing to do (even with DDD) as long as e.g. part of functionality MAY BE required in a WPF app - so we can use Service Layer with it.
Seems like the most optimal approach, doesn't it?
I'm wondering if we can omit creating Repository Layer in this case?
As explained in first paragraph here, consider using Generic Repository (DbSet) directly. Avoid creating additional layer of Repository.
Is my understanding correct?
IMO, your understanding is correct if you have correctly implemented Unit of Work (Session Per Request as you explained in question) pattern. That is how it should work.
Would it be okay to have Service Layer with DDD in such a web app?
With DDD, your domain model includes the related logic. But, there is always a logic that does not belong to any domain model. That logic generally consumed in Services. So yes, you may still need Services with DDD. Just that, it will not contain all of your logic as most of it will be in models.
With DDD, consider using CQRS. With CQRS, you separate reads and writes to your data store. Repository is optional in this case. As suggested above, you can use Generic Repository exposed by ORM.
I'm wondering if we can omit creating Repository Layer in this case?
In my opinion, you cannot omit the Repository Layer. Generally, Repository is responsible for Save and Rebuild the Aggregate Root, and your domain entity is not your database entity. EF entity is not your domain entity.
Would it be okay to have Service Layer with DDD in such a web app?
Of course you can keep your Service Layer, actually, you can call it Application Layer in DDD, but you need care what should be include in this layer.
Setup
.NET, C#, WebAPI, Entity Framework using code-first migration
Summary
I am designing a .NET solution using the repository pattern. The repository sits at the bottom of my stack and currently contains my domain models. I have layers on top of the repository (e.g. BLL) and finally I have an API layer on the top of the stack which contains my RESTful API endpoints.
Here is a simplified pseudo-diagram of the current solution stack:
-API
-BLL
-REPOSITORY
Problem
In the API layer, I would like to use .NET's ModelState validation inside each of the controller's endpoints. Problem is, this requires that the API layer have a reference to (ergo knowledge of) the Repository layer. Wouldn't this be a leaky abstraction?
It seems like the use of Data Transfer Objects would be the solution, but this almost seems silly since they would be essentially identical to the Domain Models in the Repository. That doesn't allow for much abstraction.
An alternative?
I am kicking around the idea of adding a separate project to contain the Domain Models, and then allow the API, BLL, and Repository to all reference that project. Any reason this shouldn't be done?
The only downside I see here is that now three of the projects in my solution will need access to the database:
API (because I have set up OWIN authentication in the API)
Repository
DomainModels (because I am using code-first migration)
Any help is appreciated.
The repository sits at the bottom of my stack and currently contains my domain models
That's your problem, the repository uses domain entities, but it doesn't contain them. The repo is part of the persistence, your domain model should be part of the Domain layer. The repo interface is part of the Domain too.
ALso, you domain model should be different (as a concept) than you persistence model i.e the pocos you're using with EF to do CRUD stuff. The domain objects are modelled according to the business view, the persistence pocos are designed with db usage (store/easily queryable) in mind.
The domain layer should be at the core, persistence and application services should use it i.e depend on it. You can take a look at the onion architecture or business components/ vertical slices (which is a more advanced approach IMO)
I am creating a solution from scratch, using ASP.NET Web forms C#.
I am concerned about the model objects as I don't want to create duplicate sets of model objects in each layer. What is the best practice for using Model objects in 3 layer architecture in Web Forms?
The structure I have in mind is as follows:
UI
BLL
DAL
Model
The Model will contain all the model classes that can be used in each section of the layers. I thought this would be useful as each layer needs access to the model objects. For example:
UI calls a method in BLL passing in a model object filled with data.
BLL calls a method in DAL passing through the object which is saved
in the database etc.
Thanks
Models can be a cross-cutting concern with your layers, which is a quick way to do it. Or you can create interfaces for your models such that you could simply flesh out the interface in something like the BLL - this at least stops it being cross-cutting.
It further depends on if your models are simple data containers (anemic domain model), or contain behaviour, such as the ability to validate themselves or track changes themselves (rich domain model).
You can find that your DAL actually consists of two parts: the boilerplate-never-specific to an app code to talk to the database, and the app-specific populate-the-model code. We have this situation. We share interfaces of our models around, the app-specific DAL code can use this interface in order to push and pull data from the model, but the "true" DAL code works with raw stuff.
In a relatively small application, you can share your Domain Entities all the way up to your Presentation layer but be aware of the coupling this introduces.
If in your Databinding you except an Entity of type Customer with a property Address with a StreetLine1 and StreetLine2 property then all your layers are tightly coupled together and a change in one layer will probably cause changes in other layers.
So your decision should be based on the scale of your project and the amount of coupling you can have.
If you go for a low coupled design then your BLL will use your DAL to retrieve entities and use those entities to execute behavior. The BLL will then use Data Transfer Objects to pass to your Presentation layer so there is no coupling between your presentation layer and your Domain Model.
look at my answer here: https://stackoverflow.com/a/7474357/559144 this is the usual way I do things and works well, not only for MVC and Entity Framework... in fact in MVC the model could be an entity type which only has some of the fields contained by the real business entities defined in lower layers, it depends if you really absolutely need all fields in the UI level as well or only some to do some data rendering and input...
As a related topic, please see this related answer which I posted recently on avoiding duplication of code and correct architecture in a cross-platform client/server system.
I have +1'd the other posters in this thread as this is not intended to be a full answer, just useful information related to the question.
Best regards,
Just a quick question about my Domain Layer/ Domain Service... Should I allow this layer to have read only access to the database? i.e. hook up a IReadOnlySession and only allow the Repository Layer to have access to CRUD i.e. Persistence? Or should the Repository Layer do both the ReadOnly and CRUD with the service layer making a call to the Repository layer?
One thing I find rather strange is why most of the time the Service Layer is only making a direct call to the Repo, hence the question - move out ReadOnly to the Domain Service Layer.
EDIT:
I have decided to have 3 layers in my app (for anyone who is interested in what I have done), the first layer is the WebUI (I will have 3 in total, business requiement), below this is the Domain Service i.e. All business rules, validation, checking if user can do action x, user is valid user, calling the repo for the data. The final layer is the Repository Layer i.e. the layer that talks to the database iteself, I am using LinqToSql, all my CRUD and ReadOnly logic resides here. As a side note I created another project called Model, this is the actual LinqToSql model entities i.e. Product, Item, Shop, Customer etc. This very project is referenced by the UI, Domain Service and Repo, saving me from writing DTO, and from unecessary complexity hopefully.
In your application, only one 'layer' should talk to the database.
In the Repository pattern, it's the Repository.
It doesn't matter if it's CRUD or ReadOnly, it should go through the repository to the database.
I see the discussion as what are the responsibilities of these layers. The repository is clearly to provide an abstraction over the db. Done correctly and the users of the repository cannot tell if you are using SQL server, mysql or files for persistence. This layer must have all the necessary crud operations.
The service layer is another abstraction. It may depend upon the repository for persistence. There is usually a bit more business logic. Maybe cross repository concerns or another stream of data (gps for instance).
Some apps don't need a service layer. Don't add it until you need it. If you do have the need for the service layer, letting it be a thin rapper around the repo exposing read/write allows your models to only have one direct dependency.
Scenario
Data Access Layer
EF's generated .edmx and classes
Used only to access the SQL Database and pass the data forward to the business layer
Business Layer
Business entities : contain all validation logic, marked with the [DataContract] attribute so that they can be passed as parameters to my web service
Problem
I want to use the repository pattern with this approach. The repository would contain all CRUD operations to be performed on the database, accepting and returning business layer entities. This means that the repository will reside in the business layer, because only the business layer can reference the data layer, not the other way round. I'm also planning to use the data layer assembly in other projects, that's why I would like to have the repository in the data layer, not the business layer (which is particular for this project).
What do you recommend? Should I keep the repository in the business layer and write one for each different business layer? Or should I keep the repository inside the data layer, not accepting or returning business entities.
Or, as an alternative, can anyone recommend a different approach, that would yield a more logical, scalable architecture?
Thanks for reading, waiting for answers
A repository is an abstraction over the data layer - to afford persistence ignorance to your application. It should only deal with data access and nothing more. It should not have any business logic.
The repository can and should accept and return DTOs (Data Transfer Objects) - these are simple objects that do not have behavior of their own and are used to transfer data between layers.
I would put it between the DAL and the BLL and only use it for data access from the BLL.
I like the accepted answer. Ideally, having a completely layer dedicated to the Repositories sounds right.
But I think, in a traditional 3-tier only application (e.g. "Data->Business->UI"), I would stick the Repositories in the Data layer. The reason I would put them in the Data Layer, is because they deal strictly with data access. The reason I would NOT put them in the Business Layer, is because they should NOT have any business logic to them.
I think repository interface should be in business layer, but implementation of this interface should be in data layer. Interface enable unit testing, but repository implementation is not responsibility of business layer.