n-layer business/service layer design - c#

I’m trying to reevaluate our n-layer architecture and would love to get some suggestions based on your experiences. Here is our typical .NET n-layer (sometimes n-tier) design.
Project.UI
Project.Services
Project.Business
Project.Model
Project.DataAccess
DataAccess typically consists of Entity Framework 4 and Repository classes. I attempt to follow the Aggregate Root concept in order to avoid having a repository for table, easier said than done in my experience. I tend to have ~70% match between Repositories and Tables.
Model usually consists of my Entity Framework 4 entities, I've been using Self-Tracking EF entities with success.
Business is what I struggle with the most. I typically have a Manager class for every Repository. This class will contain methods like .Add() which will perform business validation before forwarding down to repository.Add().
Services, typically I will only implement this if in fact I am looking to create a web service based solution. This layer will be tasked with marshaling requests/responses between DTOs and entities. And most importantly provide the more coarse grained interface. For example a TradingService.SubmitTrade(), which is really a facade for a business transaction which might include AccountManager.ValidateCash(), OrderManager.SubmitOrder(), etc.
Concerns
My business layer is very entity centric, really it's just the glue between the entities and the repository, with validation in between. I've seen many designs where the Service Layer is what holds a reference to the repositories (in essence skipping the "business layer"). In essence it serves the same purpose as my Business layer, it does the validation, however its' responsibility (and naming) is a higher level, more coarse grained business transaction. Using the example above the TradingService.submitTrade() will not delegate to any business manager classes, it would itself query the necessary repositories, perform all the validation etc.
I like my design in a sense that I can reuse a business layer method in multiple service calls, however I hate the fact that for every repository I have a matching business layer manager, creating tons of extra work. Maybe the solution is a different type of grouping at the Business Layer level? For example combine individual Manager classes like PhoneManager and EmailManager (note I have Phone entities and Email entities) into a logical Manager class such as ContactsManager (note I don't have a "Contact" entity type). With methods such as ContactManager.GetPhones() and ContactManager.GetEmail(), etc.
I guess more than anything I am wondering how others organize and delegate responsibilities, whether they have the Service layer, Business layer, both, etc. What holds the ORM context reference, etc.

I tend to do what you outlined near the end of your concerns, and at the business layer group things into managers that make more logical sense from a business point of view.
Using Contacts for example, I certainly wouldn't have a PhoneManager or EmailManager. "ContactsManager" is a more useful grouping to me, accomplishing pretty much the same thing only with a lot fewer managers to deal with. From a business point of view, phone numbers and emails are just small pieces of a Contact anyway. Just because they have their own tables and entities doesn't mean they need their own manager. That doesn't mean that you can't reuse them. If you have a need to do work with email addresses in several places, ContactsManager can have the relevant methods.
What we tend to have in our environment is a database/entity layer, then a business layer that sits on the server and handles business rules and business logic. That business layer is exposed as a service via WCF to the client (or at least, stuff relevant to clients is).
It sounds like you already know what you want to do, so I'd suggest doing a bit of prototyping work on it and see how it works for you. :)

Related

To Repository or Not To Repository

When I first learnt about Domain Driven Design, I was also introduced to the repository and unit of work patterns that once seemed to be top notch for the cool kids that threw SQL queries like cavemans against databases. The deeper I got into that topic, the more I learnt that they don't seem to be necessary anymore because of ORMs like EF and NHibernate that implement both unit of work and repositories into one API, called session or context.
Now I'm unsure what to do. To repository or not to repository. I really understand the argument that such leaky abstractions only over-complicate things while adding absolutely nothing that may simplify data access, however, it doesn't feel right to couple every possible aspect of my application to e.g. Entity Framework. Usually, I follow a few simple guidelines:
The domain layer is the heart of the system, containing entities, services, repositories...
The infrastructure layer provides implementations of domain interfaces of a infrastructural concern, e.g. file, database, protocols..
The application layer hosts a composition root that wire things up and orchestrates everything.
My solutions usually look like this:
Domain.Module1
Domain.Module2
IModule2Repo
IModule2Service
Module2
Infrastructure.Persistence
Repositories
EntityFrameworkRepositoryBase
MyApp
Boostrapper
-> inject EntityFrameworkRepositoryBase into IRepository etc.
I keep my domain layer clean by using a IRepository<'T> which is also a domain concern not depending on anything else that tells me how to access data. When I now would make a concrete implementation of IModule2Service that requires data access, I would have to inject DbContext and by this, coupling it directly to the infrastructure layer.
(Coming to Visual Studio project, this can end up really tricky because of circular dependencies!)
Additionally What can be an alternative to depositories and fucktons of works? CQRS? How does one abstract a pure infrastructural framework?
"Depository" lol....
Anyways, you got right the bit that you don't want the domain coupled to EF that's why the T in your repository interface should be domain aggregate root and NOT an EF entity (or a 'domain' object designed to work properly with EF).
Your Domain layer is never coupled to persistence because it only knows about abstractions. When Module2Service needs data access it either uses a DAO (or a repository - not necessarily the DDD version - if it makes sense) or the service itself is an implemented in DAL (if it doesn't contain business logic).
In your case probably the best approach is the DAO/repository which of course will 'hide' the EF part. If it seems you're writing too much code, you really aren't and I think it matters the most to keep the proper separations of concerns than saving 50 LoC (a whole 5-10 minutes).
CQRS is always good idea with a rich domain but as any solution it comes to the drawback that it requires more code (and I understand that every coder is lazy by definition, but we are required to do a 'fuckton' of work, an app doesn't build itself, a maintainable app is even more work at the beginning).
If by abstracting a pure infrastructural framework you mean hiding EF, the repository is your best bet and you don't even have to name the class 'repository', it's the principle that matters and that's what the repo does: abstracts persistence for the Domain.

Is ok to have Entity Framework inside Domain layer?

I have a project with the following structure:
Project.Domain
Contains all the domain objects
Project.EntityFramework, ref Project.Domain
Contains Entity Framework UnitOfWork
Project.Services, ref Project.Domain and Project.EntityFramework
Contains a list of Service classes that perform some operations on the Domain objects
Project.Web.Mvc, ref to all the projects above
I am trying to enforce some Business rules on top of the Domain objects:
For example, you cannot edit a domain object if it's parent is disabled, or, changing the name of an object, Category for example, needs to update recursively all it's children properties (avoiding / ignoring these rules will result in creating invalid objects)
In order to enforce these rules, i need hide all the public properties setters, making them as internal or private.
In order to do this, i need to move the Project.Services and Project.EntityFramework inside the Project.Domain project.
Is this wrong?
PS: i don't want to over complicate the project by adding IRepositories interfaces which would probably allow me to keep EntityFramework and Domain separate.
PS: i don't want to over complicate the project by adding IRepositories interfaces which would probably allow me to keep EntityFramework and Domain separate.
its really a bad idea, once i had this opinion but honestly if you dont program to abstraction it will become a pain when the project becomes larger. (a real pain)
IRepositories help you spread the job between different team members also. in addition to that you can write many helper extensions for Irepository to encapsulate Different Jobs for example
IReopisotry<File>.Upload()
you must be able to test each layer independently and tying them together will let you only do an integration tests with alot of bugs in lower layers :))
First, I think this question is really opinion based.
According to the Big Book the domain models must be separated from the data access. Your domain has nothing to with the manner of how storing the data. It can be a simple text file or a clustered mssql servers.
This choice must be decided based on the actual project. What is the size of the application?
The other huge question is: how many concurrent user use the db and how complex your business logic will be.
So if it's a complex project or presumably frequently modified or it has educational purposes then you should keep the domain and data access separated. And should define the repository interfaces in the domain model. Use some DI component (personally I like Ninject) and you should not reference the data access component in the services.
And of course you should create the test projects also using some moq tools to test the layers separately.
Yes this is wrong, if you are following Domain Driven Design, you should not compromise your architecture for the sake of doing less work. Your data-access and domain should be kept apart. I would strongly suggest that you implement the Repository pattern as it would allow you more flexibility in the long run.
There are of course to right answer to whats the right design...I would however argue that EF is you data layer abstraction, there is no way youre going to make anything thats more powerful and flexible with repositories.To avoid code repetition you can easily write extension methods (for IQueryable<>) for common tasks.Unit testing of the domain layer is easily handled by substituting you big DB with some in-proc DB (SqlLite / Sql Server Compact).IMHO with the maturity of current ORMs like nHibernate and EF is a huge waste of money and time to implement repositories for something as simple as DB access.
Blog post with a more detailed reply; http://ayende.com/blog/4784/architecting-in-the-pit-of-doom-the-evils-of-the-repository-abstraction-layer

DDD - Duplication between service layer and repositories

I've worked on several applications that try to adhere to DDD principles, I noticed that we end up with situations where there is duplication between the Service Layer and the repositories that feels like a code smell.
For most of the operations in the Service layer, it seems like it is a direct mapping to CRUD operations, GetAll, GetById, Create, Delete etc.. the flow of the architecure is within these lines: I have a controller calling a Service layer that calls a Repository that calls an ORM which talks to the Backend ..
So for example GetAll would exist in both SL and Repository. Now, if we have a change/business requirement that GetAll should ignore certain items, how am I supposed to do it, should I ignore these in the repository, or that's business logic that should go in the Service Layer? Wouldn't life be easier if we just had a Service Layer calling the ORM directly?
To Sum up: I understand the Service Layer could abstract some businees logic but when - in most cases - it is dealing with simple CRUD operations, wouldn't it be easier to just get rid of the Repository? But, what if the SL also contains some methods with complicated business logic, should these go through a repository? From good design perspective, Should I favor consistency and always go through repository or just keep it simple and only use a repository when it is not a simple one-to-one mapping to a CRUD operation.
PS: I realize there are seemingly similar questions but didn't find any satisfying answer
I noticed that we end up with situations where there is duplication
between the Service Layer and the repositories that feels like a code
smell.
It isn't a code smell since they do different things.
You should keep in mind that Domain or Application Services reside in a different layer than Repository implementations. Layers are there for a reason - objects in different layers don't have the same responsibilities and don't talk to the same neighbors. Repository implementations are tightly coupled to the means of persistence of your objects. They might generate SQL statements and talk to a relational database, they might talk to your ORM... the important thing is that they know about the way your objects are persisted, which is not true of Application Services.
If your Services layer was to call the ORM directly, it would really do 2 big things, breaking the Single Responsibility Principle. It would also be more difficult to change your ORM for another one or for a different means of persistence.
So for example GetAll would exist in both SL and Repository. Now, if
we have a change/business requirement that GetAll should ignore
certain items, how am I supposed to do it, should I ignore these in
the repository, or that's business logic that should go in the Service
Layer?
If GetAll() ignores certain items, I strongly suggest renaming it both in the Service and the Repository to reflect that, eg : GetAllAllowedToUser(), GetAllBut...(). Thus the contract of the method will be clear and you'll avoid misunderstandings about what it's supposed to return. Plus you'll be able to keep the original genuine GetAll() method which could still be of some use.
in most cases - it is dealing with simple CRUD operations, wouldn't it
be easier to just get rid of the Repository
IMHO, I wouldn't say to get rid of Repository. I would say that if you are doing CRUD you don't need DDD (at all). If you read Fowler's enterprise patterns or Evans they both say that DDD is only of use when you have domain logic that is significantly complex. CRUD is not complex and therefore no DDD needed.
What you describe is a code smell. But I don't think it is a smell with DDD. You are just seeing an over-engineered piece of code.
+1 for Dtryon, also:
Now, if we have a change/business requirement that GetAll should ignore certain item
Not directly related and I know you just used it as an example, but I've seen this exact thing. Please don't end up with methods called GetAll that do not get all. Keep GetAll, have it GetAll, then have GetAllLive, or GetAllAvailable or something like that as well which does what it says it does
Maybe the "Finder pattern"(dont know if this is the right term) can solve your problem. According to CQS(Command-Query-Separation) principle, (IMO,) query operations are not "business logic" at all. We can write some specific "Finder"s in the Infrastructure Layer to perform various queries and let all non-query operations(business logic) stay in the Service Layer, then on the client side we treat the finders the same as services.
Sorry for my language :-(.

Enterprise Design Pattern Question

Something on my mind about structuring a system at a high level.
Let's say you have a system with the following layers:
UI
Service Layer
Domain Model
Data Access
The service layer is used to populate a graph of objects in the domain model. In an attempt to avoid coupling, the domain model will be not be persistence aware and will not have any dependencies on any data access layer.
However, using this approach how would one object in the domain model be able to call other objects without being able to load them with persistence, thus coupling everything together - which I'd be trying to avoid.
e.g. an Order Object would need to check an Inventory object and would obviously need to tell the Inventory object to load in some way, or populate it somehow.
Any thoughts?
You could inject any dependencies from the service layer, including populated object graphs.
I would also add that a repository can be a dependency - if you have declared an interface for the repository, you can code to it without adding any coupling.
One way of doing this is to have a mapping layer between the Data Layer and the domain model.
Have a look at the mapping, repository and facade patterns.
The basic idea is that on one side you have data access objects and on the other you have domain objects.
To decouple you have to: "Program to an 'interface', not an 'implementation'." (Gang of Four 1995:18)
Here are some links on the subject:
Gamma interview on patterns
Random blog article
Googling for "Program to an interface, not an implementation" will yield many useful resources.
Have the domain model layer define interfaces for the methods you'll need to call, and POCOs for the objects that need to be returned by those methods. The data layer can then implement those interfaces by pulling data out of your data store and mapping it into the domain model POCOs.
Any domain-level class that requires a particular data-access service can just depend on the interface via constructor arguments. Then you can leverage a dependency-injection framework to build the dependency graph and provide the correct implementations of your interfaces wherever they are required.
Before writing tons of code in order to separate everything you might want to ask yourself a few questions:
Is the Domain Model truly separate from the DAL? And yes, I'm serious and you should think about this because it is exceedingly rare for an RDBMS to actually be swapped out in favor of a different one for an existing project. Quite frankly it is much more common for the language the app was written in to be replaced than the database itself.
What exactly is this separation buying you? And, just as important, what are you losing? Separation of Concerns (SoC) is a nice term that is thrown about quite a bit. However, most people rarely understand why they are Concerned with the Separation to begin with.
I bring these up because more often than not applications can benefit from a tighter coupling to the underlying data model. Never mind that most ORM's almost enforce a tight coupling due to the nature of code generation. I've seen lot's of supposedly SoC projects come to a crash during testing because someone added a field to a table and the DAL wasn't regenerated... This kind of defeats the purpose, IMHO...
Another factor is where should the business logic live? No doubt there are strong arguments in favor of putting large swaths of BL in the actual database itself. At the same time there are cases where the BL needs to live in or very near your domain classes. With BL spread in such a way, can you truly separate these two items anyway? Even those who hate the idea of putting BL in a database will fall back on using identity keys and letting the DB enforce referential integrity, which is also business logic..
Without knowing more, I would suggest you consider flattening the Data Access and Domain Model layers. You could move to a "provider" or "factory" type architecture in which the service layer itself doesn't care about the underlying access, but the factory handles it all. Just some radical food for thought.
You should take a look at Martin Fowler's Repository and UnitOfWork patterns to use interfaces in your system
Until now I have seen that application can be well layered into three layers: Presentation-->Logic-->Data--and Entities (or Bussines Object). In the Logic Layer case you can use some pattern such as Transaction Script or Domain Model I'm supposing you're using this last. The domain model can use a Data Mapper for interacting with the data layer and create business objects, but you can also use a Table Module pattern.
All this patterns are described in Marttin's Fowler Patterns of Enterprise Application Architecture book. Personally I use Transaction Script because it is simplest than Domanin Model.
One solution is to make your Data Access layer subclass your domain entities (using Castle DynamicProxy, for example) and inject itself into the derived instances that it returns.
That way, your domain entity classes remain persistence-ignorant while the instances your applications use can still hit databases to lazy-load secondary data.
Having said that, this approach typically requires you to make a few concessions to your ORM's architecture, like marking certain methods virtual, adding otherwise unnecessary default constructors, etc..
Moreover, it's often unnecessary - especially for line-of-business applications that don't have onerous performance requirements, you can consider eagerly loading all the relevant data: just bring the inventory items up with the order.
I felt this was different enough from my previous answer, so here's a new one.
Another approach is to leverage the concept of Inversion of Control (IoC). Build an Interface that your Data Access layer implements. Each of the DAL methods should take a list of parameters and return a Data Table.
The service layer would instantiate the DAL through the interface and pass that reference to your Domain Model. The domain model would then make it's own calls into the DAL, using the interface methods, and decide when it needs to load child objects or whatever.
Something like:
interface IDBModel {
DataTable LoadUser(Int32 userId);
}
class MyDbModel : IDBModel {
DataTable LoadUser(Int32 userId) {
// make the appropriate DB calls here, return a data table
}
}
class User {
public User(IDBModel dbModel, Int32 userId) {
DataTable data = dbModel.LoadUser(userId);
// assign properties.. load any additional data as necessary
}
// You can do cool things like call User.Save()
// and have the object validate and save itself to the passed in
// datamodel. Makes for simpler coding.
}
class MyServiceLayer {
public User GetUser(Int32 userId) {
IDBModel model = new MyDbModel();
return new User(model, userId);
}
}
With this mechanism, you can actually swap out your db models on demand. For example, if you decide to support multiple databases then you can have code that is specific to a particular database vendors way of doing things and just have the service layer pick which one to use.
The domain objects themselves are responsible for loading their own data and you can keep any necessary business logic within the domain model. Another point is that the Domain Model doesn't have a direct dependency on the data layer, which preserves your mocking ability for independent testing of business logic.
Further, the DAL has no knowledge of the domain objects, so you can swap those out as necessary or even just test the DAL independently.

Generic business layer design with repository pattern with c# (how)

I am using a repository design with web applications (repository (data layer) exposing model (objects) to the business layer which is then consumed to the data layer (ui). Objects or lists of objects are passed between the layers with this type of implementation.
I am finding my business layer is a becoming a series of manager type classes which all have common GetAll, GetById, Save, Delete type methods. This is very common with a number of very small simple objects. This is the area of concern or opportunity for improvement (the series of smaller business manager classes). I am looking for options to avoid the whole series of smaller business manager classes mapping to the smaller objects which only do get/save/delete object.
The bigger objects which are closer to the functionality to the application have a number of methods in addition to the get/save/delete type methods (these manager classes are ok).
I am thinking there is a design pattern or implementation which will allow me to have one manager class which resides in the business layer which would accept an object as a parameter of a particular object type and the get/save/delete methods respectively know the type of repository object to spin up and pass the object to it for its operation.
The benefit here would be that I can have one generic manager class to pass save/delete/get's for smaller type objects to the appropriate repository class thereby reducing the many smaller manager classes.
Ideas on how to accomplish this?
thx
I would not go that way. The business layer classes can be as simple as code that forwards to the data layer, and it is true that they can be annoying to write, but they exist for a couple of reasons: validation, security, taking some actions based on business rules.
If you try to make a generic business layer, it will hard to include all the various things that a business class could do. The generic business layer will become much more complex than the one you currently have. Testing will be much harder. Adding a new business rule will be hard, too.
Sorry, this is not what you wanted to read, but I have already gone the route of generic systems and have always had lots of regrets.
The idea behind a repository (or a dao), is to further abstract data access concerns away from the business layer in order to simplify that layers focus on the "business" of a given domain.
That said, there are many common plumbing type of concerns that are reuseable across different applications, some of which do lend themselves to a supertype in the business layer. Consider the cross cutting concern of being able to retrieve a given business entity by some Id from a database, and you might come to the conclusion that it is in fact useful to have an Id property in a business layer supertype. It might even be useful if entities considered that Id when determining equality. Etc..
Now I do believe that Timores is right in principal and trying to write one application that fits all domains is both incredibly painful and totally fruitless, but I also beleive the the art of the profession is knowing how to use a variety of tools and when to apply which one, and having some core infrastructure code should be in your tool belt.
For a good idea of a framework concept for a web app that has been road tested, take a look at SharpArch.
HTH,
Berryl

Categories