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.
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 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.
I'm interested in using entity framework - code first migrations with a new database, and I have some questions/concerns about duplicating POCO code in the data and business layers.
The idea is to have a data access layer containing my POCO entities all decorated with database schema type items like string lengths, foreign key related things that don't work out of the box, and whatever else. This layer will also act as a repository that will return scalar values, entities, aggregates, and IEnumerables.
Above that will be the business layer, which will handle talking to the repository, and a bunch of business logic.
At the top is the presentation layer. This layer talks to the business layer, and has no idea about the data layer – all it understands is view models. I would implement the MVC pattern at this layer, using only view models.
The issue I am running into is related to where I should do the mapping between my view models and my data models. If I define the view models in my presentation layer, the business layer will not know they exist.
Am I better off defining the view models in the business layer, or do I need a set of domain models in the business layer that the presentation layer would be aware of and be able to perform mapping against?
Would an additional set of domain models just be an egregious duplication of the models defined in the data layer?
Depending on the scope of the project, I usually use one of the two methods below:
1) have a set of domain models separately from all layers, and then have all layers reference them.
Pros: layers are still independent, no model duplication, no need to map layer models.
Cons: change in domain model would affect all layers, e.g. DB change may break display
2) have models in each layer. Business layer would map its own models to those of data layer, presentation layer would map its models to those of business layer
Pros: every layer does one thing, changes in underlying models to not propagate through layer
Cons: duplication of the models is likely and mapping needs to be maintained
First approach works best for smaller apps and "direct updates" scenarios, second works better in large projects with multiple moving components.
P.S. "defining the view models in the business layer" is a definite no-no.
I have developed an application with following layers:
Data access layer based on fluent nHibernate
Business rules
activity layer(more abstract than business rules and use some
business rules)
service layer based on WCF that sends some DTOs to the outside world
and recieves DTOs.
so when some DTO came back, I can map the DTO to business objects in the service layer and made my application to work with business objects. in that case when some function in lower layers executes it does not know any thing about the old object, so it become hard to handle and verify state changing and also there is class explosion for DTO adapters.
on the other hand if dto is mapped to business object on the higher layers, when it came down, the lower layers did not know anything about the service which is called, so they can not unserstand how this dto must change the business objects(1 DTO might be used by different services in different ways)
so the question is what is the real solution??
From your specs, I'm kind of assuming you are aiming for a DDD based implementation
First, some assumptions to help map this to more common terminology: I assume your "Business Rules" layer is just used by your activity layer, and thus can be considered as part of the domain layer.
You mention business objects. I assume then that you have a domain layer. This might be your "activity layer". This should be the layer that knows how to update objects and return them to the service layer.
The service layer (or "application layer" in DDD terms) should be mapping the DTOs, and invoking domain services. MS has a decent diagram here. But basically the workflow should be:
Send DTO to service layer
Service layer invokes DTO adapters to create domain objects/entities out of DTOs.
Service layer invokes domain services to perform business logic (invokes rules)
Domain services update domain objects as a result of business rules
Persistance layer is invoked by domain services as needed
Domain services return updated domain objects to service layer
Service layer maps domain objects back to DTO and returns them
There are of course many variations on this theme, but this should be your starting point.
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.
I have an application with three layers (Presentation, Business Logic, and Data Access). In the data access layer, I have an object called Unit, and I have another object called Unit in the business layer.
When Insert() is called on the Unit object in the business layer, it calls the Insert() method on the corresponding object in the data access layer, and passes itself as the parameter. The problem I have is that the data access layer does not reference the business layer, and allowing it to do so would cause circular dependencies.
Is my approach flawed? If so, what would be a good solution to my problem?
You're right when you state that the way you're doing it would require a bidirectional dependency between layers, and that's almost always a bad thing. The reason for this dependency is that your business logic layer takes on some of the responsibility of the persistence layer (by implementing Insert() in the business logic layer).
It seems like you're mixing two incompatible concepts here.
First, you state that you have three layers in your code: presentation, business, and data access. The problem with this statement is that you also claim to be using an active record like pattern (unit.Insert()). If you truly have a distinct domain (business) layer and persistence (data access) layer, then the domain objects would not know how to Insert().
Take a look at the repository pattern. This pattern is better suited for establishing a distinct persistence layer. If you use this pattern, you can define an "Entity" in the persistence layer, and map your Unit object in the domain layer to the Unit object in the persistence layer. AutoMapper should save you from the pain of manually mapping the domain model to the entity.