Using View-Models with Repository pattern - c#

I'm using Domain driven N-layered application architecture with EF code first in my recent project, I defined my Repository contracts, In Domain layer.
A basic contract to make other Repositories less verbose:
public interface IRepository<TEntity, in TKey> where TEntity : class
{
TEntity GetById(TKey id);
void Create(TEntity entity);
void Update(TEntity entity);
void Delete(TEntity entity);
}
And specialized Repositories per each Aggregation root, e.g:
public interface IOrderRepository : IRepository<Order, int>
{
IEnumerable<Order> FindAllOrders();
IEnumerable<Order> Find(string text);
//other methods that return Order aggregation root
}
As you see, all of these methods depend on Domain entities.
But in some cases, an application's UI, needs some data that isn't Entity, that data may made from two or more enteritis's data(View-Models), in these cases, I define the View-Models in Application layer, because they are closely depend on an Application's needs and not to the Domain.
So, I think I have 2 way's to show data as View-Models in the UI:
Leave the specialized Repository depends on Entities only, and map the results of Repositories's method to View-Models when I want to show to user(in Application Layer usually).
Add some methods to my specialized Repositories that return their results as View-Models directly, and use these returned values, in Application Layer and then UI(these specialized Repositories's contracts that I call them Readonly Repository Contracts, put in Application Layer unlike the other Repositories'e contract that put in Domain).
Suppose, my UI needs a View-Model with 3 or 4 properties(from 3 or 4 big Entities).
It's data could be generate with simple projection, but in case 1, because my methods could not access to View-Models, I have to fetch all the fields of all 3 or 4 tables with sometimes, huge joins, and then map the results to View-Models.
But, in case 2, I could simply use projection and fill the View-Models directly.
So, I think in performance point of view, the case 2 is better than case 1. but I read that Repository should depend on Entities and not View-Models in design point of view.
Is there any better way that does not cause the Domain Layer depend on the Application layer, and also doesn't hit the performance? or is it acceptable that for reading queries, my Repositories depend on View-Models?(case2)

Perhaps using the command-query separation (at the application level) might help a bit.
You should make your repositories dependent on entities only, and keep only the trivial retrieve method - that is, GetOrderById() - on your repository (along with create / update / merge / delete, of course). Imagine that the entities, the repositories, the domain services, the user-interface commands, the application services that handles those commands (for example, a certain web controller that handles POST requests in a web application etc.) represents your write model, the write-side of your application.
Then build a separate read model that could be as dirty as you wish - put there the joins of 5 tables, the code that reads from a file the number of stars in the Universe, multiplies it with the number of books starting with A (after doing a query against Amazon) and builds up a n-dimensional structure that etc. - you get the idea :) But, on the read-model, do not add any code that deals with modifying your entities. You are free to return any View-Models you want from this read model, but do trigger any data changes from here.
The separation of reads and writes should decrease the complexity of the program and make everything a bit more manageable. And you may also see that it won't break the design rules you have mentioned in your question (hopefully).
From a performance point of view, using a read model, that is, writing the code that reads data separately from the code that writes / changes data is as best as you can get :) This is because you can even mangle some SQL code there without sleeping bad at night - and SQL queries, if written well, will give your application a considerable speed boost.
Nota bene: I was joking a bit on what and how you can code your read side - the read-side code should be as clean and simple as the write-side code, of course :)
Furthermore, you may get rid of the generic repository interface if you want, as it just clutters the domain you are modeling and forces every concrete repository to expose methods that are not necessary :) See this. For example, it is highly probable that the Delete() method would never be used for the OrderRepository - as, perhaps, Orders should never be deleted (of course, as always, it depends). Of course you can keep the database-row-managing primitives in a single module and reuse those primitives in your concrete repositories, but to not expose those primitives to anyone else but the implementation of the repositories - simply because they are not needed anywhere else and may confuse a drunk programmer if publicly exposed.
Finally, perhaps it would be also beneficial to not think about Domain Layer, Application Layer, Data Layer or View Models Layer in a too strict manner. Please read this. Packaging your software modules by their real-world meaning / purpose (or feature) is a bit better than packaging them based on an unnatural, hard-to-understand, hard-to-explain-to-a-5-old-kid criterion, that is, packaging them by layer.

Well, to me I would map the ViewModel into Model objects and use those in my repositories for reading / writing purposes, as you may know there are several tools that you can do for this, in my personal case I use automapper which I found very easy to implement.
try to keep the dependency between the Web layer and Repository layers as separate as possible saying that repos should talk only to the model and your web layer should talk to your view models.
An option could be that you can use DTO's in a service and automap those objects in the web layer (it could be the case to be a one to one mapping) the disadvantage is that you may end up with a lot of boilerplate code and the dtos and view models could feel duplicated.
the other option is to return partial hydrated objects in your model and expose those objects as DTOs and map those objects to your view models this solution could be a little bit obscure but you can make the projections you want and return only the information that you need.
you can get rid of the of the view models and expose the dtos in your web layer and use them as view models, less code but more coupled approach.

I Kindof agree with Pedro here. using a application service layer could be benificial. if your aiming for an MVVM type of implementation i would advise to create a Model class that is responsible for holding the data that is retrieved using the service layer. Mapping the data with automapper is a really good idea if your entities, DTO's and models are named consistently (so you don't have to write a lot of manual mappings).
In my experience using your entities/poco in viewmodels to display data will result in big balls of mud. Different views have different needs en will all add a need to add more properties to an entity. Slowly making your queries more complex and slower.
if your data is not changing that often you might want to consider introducing (sql/database) views that will transfer some of the heavy lifting to the database (where it is highly optimized). EF handles database views fairly well. Then retrieving the entity and mapping the data (from the views) to the model or DTO becomes fairly straightforward.

Related

Abstracting Data Access Layer with Entity Framework code first

I have two separate databases. Database A is small and contains 6 tables and some stored procedures, database B is larger and contains 52 tables, 159 views, and some stored procedures. I have been tasked with creating an application that does operations on both of these databases. There is already code that has been written that accesses these databases but it is not testable and I would like to create the DAL code from scratch. So I made a code first Entity Framework connection and let it create all of the POCOs for me as well as the Context classes. Now I have 3 DatabaseContext classes. 1 for database A which is just the 6 separate tables. 1 for the tables from database B and 1 for the views from database B. I split the Context class for database B into 2 separate context classes because the tables and the views are used in 2 different scenarios.
I have created 2 projects in a single solution. DomainModel and DataAccessLayer. The DomainModel project holds all of the POCOs which the Entity Framework code first generated for me. DataAccessLayer is where the DatabaseContexts are and where I would like to create the code which other projects can use to access the database. My goal being to make a reusable and testable data access layer code.
The QUESTION is: What do I create in the DataAccessLayer project to make the DAL resusable in other projects that want to be able to talk to the database in an abstract way and what is the best way to structure it?
What I have done:
In my search on the internet I have seen that people recommend the repository pattern (sometimes with UnitOfWork) and it seems like that is the way to go, so I created an interface called IGenericRepository and an implementation called GenericEntityFrameworkRepository. The interface has methods such as GetByID, Insert, Delete, and Update. The implementation takes a DbContext as a parameter in the constructor and implements all of the methods. The next step might be to create specific implementations for the different tables and views but that is going to be a very tedious thing to do since there are so many tables and views.
I have also read that Entity Framework IS the DAL. Then it might be enough to just create another project that holds the business logic and returns IEnumerables. But that seems like it will be hard to test.
What I am trying to achieve is a well structured and testable foundation to access our database that can be tested thoroughly and expanded as other projects start to require other functionality to the database.
The folder structure for the project can be seen in the following picture:
Design and architecture is all about trade-offs. Be careful when you want to consider abstracting your data access for purposes of reuse. Within an application this leads to overly complex and poorly performing solutions to what can be a very simple and fast solution.
For instance, if I want to build a business domain layer as a set of services to be consumed by a number of different applications (web applications and services/APIs that will serve mobile apps or third party interests) then that domain layer becomes a boundary that defines what information will come in, and what information will go out. Everything in and out of that abstraction should be DTOs that reflect the domain that I am making available via the actions I make available. Within that boundary, EF should be leveraged to perform the projection needed to produce the relevant DTOs, or update entities based on the specific details passed in. (After verification) The trade-off is that every consumer will need to make due with this common access point, so there is little wiggle room to customize what comes out unless you build it in. This is preferable to having everything just do their own thing accessing the database and running custom queries or calling Stored Procedures.
What I see most often though is that within a single solution, developers want to abstract the system not to "know" that the data domain is provided by EF. The application passes around POCO Entities or DTOs and they implement things like Generic Repositories with GetById, GetAll, Update, Upsert, etc. This is a very, very poor design decision because it means that your data domain cannot take advantage of things like projection, pagination, custom filtering, ordering, eager loading related data, etc. Abstracting the EF DbContext is certainly a valid objective for enabling unit testing, but I strongly recommend avoiding the performance pitfall of a Generic Repository pattern. IMO attempting to abstract away EF just for the sake of hiding it or making it swappable is either a poor performing and/or an overly complex mess.
Take for example a typical GetAll() method.
public IEnumerable<T> GetAll()
{
return _context.Set<T>().ToList();
}
What happens if you only want orders from the last 3 months?
var orders = orderRepository.GetAll()
.Where(x => x.OrderDate >= startDate).ToList();
The issue here is that GetAll() will always return all rows. If you have 4 million orders you can appreciate that is not desirable.
You could make an OrderRepository that extends Repository to implement a method like GetOrdersAfter(DateTime) but soon, what is the point of the Generic Repository? The next option would be to pass something like an Expression<Func<TEntity>> Where clause into the GetAll() method. There are plenty of examples of that out there. However, doing that is leaking EF-isms into the consuming code. The Where clause expression has to conform to EF rules. For instance passing order => order.SomeUnmappedProperty == someValue would cause the query to fail as EF won't be able to convert that down to SQL. Even if you're Ok with that the GetAll method will need to start looking like:
IEnumerable<TEntity> GetAll(Expression<Func<TEntity>> whereClause = null,
IEnumerable<OrderByClause> orderByClauses = null,
IEnumerable<string> includes = null,
int? pageNumber = null, int? pageSize = null )
or some similar monstrosity to handle filtering, ordering, eager loading, and pagination, and this doesn't even cover projection. For that you end up with additional methods like:
IEnumerable<TEntity, TDTO> GetAll(Expression<Func<TEntity>> whereClause = null,
IEnumerable<OrderByClause> orderByClauses = null,
IEnumerable<string> includes = null,
int? pageNumber = null, int? pageSize = null )
which will call the other GetAll then perform a Mapper.Map to return a desired DTO/ViewModel that is hopefully registered in a mapping dependency. Then you need to consider async vs. synchronous flavours of the methods. (or forcing all calls to be synchronous or async)
Overall my advice would be to avoid Generic Repository patterns and don't abstract away EF just for the sake of abstraction, instead look for ways to leverage the most you can out of it. Most of the problems developers run into with performance and odd behaviour with EF stem from efforts to abstract it. They are so worried about needing to abstract it to be able to replace it if they need to, that they end up with those performance and complexity problems entirely because of the limitations imposed by the abstraction. (A self-fulfilling prophecy) "Architecture" can be a dirty word when you try to prematurely optimize a solution to solve a problem you don't currently, and probably will never face. Always keep YAGNI and KISS at the forefront of all design considerations.
I guess you tumbled between selecting right architecture for a given solution. a software must be created for meet the business needs. so depending on the business, complexity of the domain, we have to choose the write architecture.
Microsoft elaborated this in a detail PDF you will find it here
https://learn.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/
You want some level of abstraction between your Data and the BL then "N-Layer" architecture is not the best solution. even though i am not telling the N-Layer entirely out dated but there is more suitable solutions for this problem .
And if you using EF or EF core then there is no need to implement Repository cus EF itself contain UOW and Repositories.
Clean Architecture introduce higher level of abstraction between layers. it abstract away your data layer and make it reusable over different project or different solutions. Clean architecture is a big topic i can't describe here in more details. but i learn the subject from him.
Jason Taylor- Clean Architecture
https://www.youtube.com/watch?v=dK4Yb6-LxAk
https://github.com/jasontaylordev/CleanArchitecture

Is it appropriate for a Factory class to also include functionality of extracting data from a database

One of the main aspects of software development that I struggle with is delegating the correct responsibility into classes within my program. Working at my first junior role I'm also being exposed to a lot of different design patterns and ideas, and sometimes the information can be overwhelming.
Obviously when we are building software we tend to state that a class should be responsible for one thing and one thing only. It should do that thing well and nothing more. So in the case of the Factory pattern the Factory class should be responsible for building the product and exposing an interface that allows the director to extract the product from the factory.
However the factory class obviously needs to receive the data to build the product from somewhere, without input data we have no output product. Therefore I'd like to know whether including functionality for a factory to query a database is appropriate? My rationale for this is that if the factory is tasked with building a particular product, then it should also be responsible for retrieving the data required to build that product. But I'm not 100% sure if this is correct.
Alternatively, should there be a repository class who's responsibility is to retrieve the data in question from the database, which can be then passed to the factory for assembly into the required product? The use of a repository class seems a bit excessive in this case as we have a class that will hold a large number of different pieces of data which then must be shipped into the factory class.
If we also bear in mind Uncle Bob's teachings that state that functions and methods should have absolutely no more than three parameters then we will be breaking this rule by passing in a large amount of data to the factory. If we first assemble the data into an encompassing class before passing to the factory then we are essentially doing the factory's job within the repository class.
Some guidance would be really appreciated on this, as in my head the lines are very blurry and I'm not sure how I should proceed.
You shouldn't use the factory pattern to object building that extracted from a database. There are the Repository pattern and the Data Mapper pattern for this goal. Those patterns must encapsulate all logic of work with the data storage. Those patterns must have the following responsibility:
the Repository must give an interface to business logic for work with data storage
the Data Mapper must convert data from database to concrete object
The algorithm of cooperation between objects can look like:
business logic uses a repository to read/persist objects.
the repository uses a Data Mapper to convert objects to INSERT or UPDATE queries and to convert data from data storage to object
Also, you can read more details about the repository pattern in C# on the site of Microsoft and you can see C# example of the repository pattern
Use 2 different classes.
A Data Access Object (DAO) provides an abstract interface to the database, and hides its details.
A factory abstracts and hides the details of the creation of your objects. For example, for unit testing you might want to configure the factory so that it doesn't use the Database at all.
To reduce the number of parameters between the DAO and the factory, wrap your many pieces of data in a few logically related classes.
Is it apropriate for a Factory class to also include functionality of extracting data from a database
My rationale for this is that if the factory is tasked with building a particular product, then it should also be responsible for retrieving the data required to build that product. But I'm not 100% sure if this is correct.
A product to retrieve from database is not a trivial object, it is a domain model.
A domain model (aka business model, aka entity(which might indicate a particular instance of it)) belongs to your domain layer (aka business layer).
In this regard, there are some patterns you should be a minimum familiar with...
(Active Record) VS (Data Mapper + Repository) VS (Table Data Gateway + Factory)
Active record pattern kind of violate the Single Responsibility Principle by leading you to implement database access logic inside your domain model and tightly couples them.
Ideally, to avoid the cons above for the cost of a slightly increased complexity (on short term only), we separate the database access logic into a supplementary layer, the data access layer. One of the main component of this layer being the data mapper which in our context (READ operation) is in charge to retrieve data from database and map it to a new domain model instance, your specific product (entity). More generally it encapsulates CRUD operations to the database abstracting this database. Its API inputs and outputs are entity objects and possibly Query Objects.
Optionally, a featured data mapper would make use of patterns such as:
Unit Of Work
Lazy Loading
Identity Map
Transaction
Lock Strategies
Metadata Mapping
Alternatively, should there be a repository class who's responsibility is to retrieve the data in question from the database, which can be then passed to the factory for assembly into the required product? The use of a repository class seems a bit excessive in this case as we have a class that will hold a large number of different pieces of data which then must be shipped into the factory class.
Repository is not a part of your data access layer, but of your domain layer. So it is client of your data access layer. It doesn't encapsulate any database access logic but uses the data mapper.
A repository encapsulates query logic for a particular domain model plus a collection of in-memory entities you've previously retrieved.
A very basic example:
class ProductRepository
{
private $productCollection;
public function findById($id)
{
if (!$this->productCollection->has($id)) {
$product = $this->dataMapper->get(new Query(Product::class, $id));
$this->productCollection->add($product);
return $product;
}
return $this->productCollection->get($id);
}
}
Finally, we can encapsulate database access logic in a table data gateway and use it in a factory. This would result in a solution similar to Gonen I's one. It is simple to implement but there might be cons compared to the data mapper solution. I've never implemented, used or even studied this approach so I can't tell much...
You'd definitely learn a lot by attempting to implement all that by yourself and I'd encourage you to, but keep in mind that if you need a serious solution, ORMs might be interesting for you.
If you're keen to learn more about all this, I recommend Martin Fowler's Patterns of Enterprise Application Architecture book which is summarized here: https://www.martinfowler.com/eaaCatalog/index.html

Seperation of models in a web api application

My team devolops a web api application using entity framework,
The Gui is developed by a seperate team.
My question is how should the models be defined? Should we have two projects - one for domain models (database entities) and one for Dtos which are serializable?
Where should the parsing from Dto to domain models should happen and when should it happen the opposite way?
Moreover, sometimes all the data is needed to be sent to the clients.. Should a Dto be created for those cases as well? Or should I return a domain model?
Generally speaking, it's a good idea to not let your entities (database models) leak out of your database layer. However, as with everything in software - this can have its downfalls. One such downfall being is that it starts to increase complexity of your data layer as it involves mapping your entities to their DTO within your database layer, ultimately leaving repositories that are full of similar methods returning different DTO types.
Some people also feel that exposing IQueryables from your data layer is also a bad thing as you start to leak abstractions to different layers - though this has always seemed a little extreme.
Personally, I favour what I feel is a more pragmatic approach and I prefer to use a tool like AutoMapper to automatically map my entities to my DTOs within the business logic layer.
For example:
// Initial configuration loaded on start up of application and cached by AutoMapper
AutoMapper.Mapper.CreateMap<BlogPostEntity, BlogPostDto>();
// Usage
BlogPostDto blogPostDto = AutoMapper.Mapper.Map<BlogPostDto>(blogPostEntity);
AutoMapper also has the ability to configure more complex mapping, though you should try and avoid this if possible by sticking to flatter DTOs.
In addition, another great feature of AutoMapper is the ability to automatically project your entities to DTOs. This results in much cleaner SQL where only the columns within your DTO are queried:
public IEnumerable<BlogPostDto> GetRecentPosts()
{
IEnumerable<BlogPostDto> blogPosts = this.blogRepository.FindAll().Project(this.mappingEngine).To<BlogPostDto>().ToList();
return blogPosts;
}
Moreover, sometimes all the data is needed to be sent to the clients.. Should a Dto be created for those cases as well? Or should I return a domain model?
DTOs should be created for those. Ultimately you don't want your client depending on your data schema, which is exactly what will happen if you expose your entities.
Alternatives: Command/Query Segregation
It behooves me to also highlight that there are also some other alternatives to a typical layered architecture, such as the Command/Query Segregation approach where you model your commands and queries via a mediator. I won't go into it in too much detail as it's a whole other subject but it's one I would definitely favour over a layered approach discussed above. This would result in you mapping your entities to your DTOs directly within the modelled command or query.
I would recommend taking a look at Mediatr for this. The author, Jimmy Bogard who also created AutoMapper also has this video talking about the same subject.
I've had similar requirements in several projects and in most cases we separated at least three layers:
Database Layer
The database objects are simple one-to-one representations of the database tables. Nothing else.
Domain Layer
The domain layer defines entity objects which represent a complete business object. In our defintion an entity aggregates all data which is directly associated to the entity and can not be regarded as a dedicated entity.
An exmaple: In an application which handles invoices you have a table invoice and invoice_items. The business logic reads both tables and combines the data into a entity object Invoice.
Application Layer
In the application layer we define models for all kind of data we want to send to the client. Pass-through of domain entity objects to save time is tempting but strictly prohibited. The risk to publish any data which shouldn't be published is too high. Furthermore you gain more freedom regarding the design of your API. That's what helps you to fit your last requirement (send all data to the client): Just built a new model which aggregates the data of all domain objects you need to send.
This is the minimum set of layers we use in all projects. There were hundreds of cases where we've been very happy to have several abstraction layers which gave us enough possibilities to enhance and scale an application.

Data Layer Architecture with multiple datasources

I am trying to create a system that allows you to switch multiple data sources, e.g. switching from Entity Framework to Dapper. I am trying to find the best approach to do this.
At the moment I have different projects for different data layers, e.g. Data.EF for Entity Framework, Data.Dapper for Dapper. I have used a database approach but when it creates the models the information generated is coupled together and not easy to refactor, e.g. separation of models.
I have a project called models, this holds domain and view models, and I was thinking of creating Data.Core and follow the repository pattern. But then, doing this will add an extra layer so I would have Presentation / Business / Repository / Data.
I would like to know the best structure for this approach. Should I also do a code-first approach to create my database? This helps separate concerns and improve abstraction. This is quite a big application so getting the structure right is essential.
I'd suggest factoring your data interfaces either to the model through repository interfaces for your entities or to an infrastructure project. (I think the latter was your rationale behind creating a Data.Core project.)
Each data source will then implement the very same set of interfaces, and you can easily switch between them, even dynamically using dependency injection.
For instance, using repositories:
Model
\_ Entities
Entity
\_ Repositories
IEntityRepository
Data.EF
EntityRepository : Model.IEntityRepository
Data.Dapper
EntityRepository : Model.IEntityRepository
Then in your business you won't need to even reference Data.EF or Data.Dapper: you can work with IEntityRepository and have that reference injected dynamically.
I think you approach is correct. I'd say Presentation / business / repository / data is pretty standard these days.
I'd say the code first approach using POCOs is the preferred option today in the industry. I would advise to start creating a project containing your POCO data structures with any logic in it and take it from there. The advantage of this is that your objects model the domain more naturally. If you start with a db centric approach the problem is that, if you are not careful, you may end with objects more akin to SQL relational databases than to the real model. This was painfully evident in the first versions of .net where it was encouraged to use Datasets tighly coupled with the db and that often caused problems to work with in the business layer.
If needed you can do any complex mapping between the business objects and the db objects in the repository layer. You can use a proxy and/or a unit of work if you need to.
I would suggest you create your domain objects, use the code-first approach and also apply the repository pattern
Yes the repository pattern does bring in an extra layer. Have a look at this post for more detail information Difference between Repository and Service Layer?
RE: code-first approach to create my database
It doesn't matter how big your application is, it is a question of what else you intend to use the database for. If this database is simply a repository for this application then using code-first is fine as you are simply storing your code objects. However if you are using this database as an integration point between applications then you may wish to design the database seperately to the application models.

How to handle views in a multilayer-application

I'm working on a project which has basically three layers: Presentation, business and data.
Each layer is on a different project and all layers use DTO's defined in another project.
business layer and data layer return DTO's or Lists of DTOs when querying the database.
So far so good, but now we have to query views and those views of course do not match an existant DTO. What we have done until now is just create a special DTO, business- and data-layer classes so they were treated like normal entities (minus insert, update etc.)
But it does not seem correct. Why should the be treated like normal entities when they are clearly not. Well the DTO seems necessary, but creating "business logic" and a datalayer-class for every view seems rather akward. So I thought I create one generic business- and datalayer class which holds the logic/code for all views (I still would have to create a DTO for every different view, perhaps I could use anonymous types)
What do you think about me idea or how would you solve this issue?
EDIT: 9. August 2011
Sorry, the post may have been unclear.
By views I meant Views from a sql-server.
I feel your pain completely. The fact is that in almost every non trivial project with decent complexity you will get to the point where the things you have to show to the users on UI overlap, aggregate or are simply a subset of data of business entities. The way I tend to approach this is to accept this fact and go even further - separate the query side from the business logic side both logically and physically. The fact is that you need your entities only for actual business operations and keeping the business constraints valid, and when does this happen? Only when someone changes the data. So there is no need to even build entities when you display the data.
The way I like to structure the solutions is:
User opens the view -> Query is performed only to get the specific
data for the view -> Returned data is the model (although you could
call it a DTO as well, in this case it's the same thing)
User changes something -> Controller (or service) builds the full entity from repo,
business logic action is performed on the entity -> changes are
persisted -> result is returned
What I want to say is, it is ok to treat your read side separately from write side. It is ok to have different infrastructure for this as well. When you start to treat it differently, you will see the benefits - for example you can tailor you queries to what you need on UI.
You can even get to the point where your infrastructure will allow to build your queries with different techniques, for example using LINQ or plain SQL queries - what is best for certain scenarios.
I would advise against using DTOs between layers. I'm not convinced that there's any benefit, but I'll be happy to take instruction if you think you have some.
The harm comes in maintaining multiple parallel hierarchies that express the same idea (business objects plus multiple DTOs between layers). It means lots more code to maintain and greater possibility of errors.
Here's how I'd layer applications:
view <--- controller <--- service <--- + <--- model
+ <--- persistence
This design decouples views from services; you can reuse services with different views. The service methods implement use cases, validate inputs according to business rules, own units of work and transactions, and collaborate with model and persistence objects to fulfill requests.
Controller and view are tightly coupled; change the view, change the controller. The view does nothing other than render data provided by the controller. The controller is responsible for validation, binding, choosing the appropriate services, making response data available, and routing to the next view.
Cross cutting concerns such as logging, transactions, security, etc. are applied at the appropriate layer (usually the services).
Services and persistence should be interface-based.
I've dropped most layered architectures like this as they are a pain to manage all the transformations and are over-complicated. It's typical astronaut architecture. I've been using the following:
View models for forms/views in ASP.Net MVC. This is an important decoupling step. The UI will evolve separately to the model typically.
No service layer, instead replacing it with "command handlers" (mutating operations) and "finders" (query operations) which represent small operations and queries respectively (CQS - Command Query Separation).
Model persistence with NHibernate and ALL domain logic inside the model.
Any external services talk to the finders and command handlers as well
This leads to a very flat manageable architecture with low coupling and all these problems go away.

Categories