We have a website application and a web services layer. The website must use the web service for data per our requirements. Both layers are being build by me. I'm curious if my layout for DI is justified.
Common entities project - shared by both the website and web service layer
ASP.NET MVC website
-- MVC service layer - injects concrete class to contain business rules for the website/pages
-- -- Data repository - injected by MVC service layer. In this case, various wrappers for web service calls currently, but things may change
Web services
-- Service/business layer - injected classes to handle business logic for services
-- -- Data repository - injected data classes used by business layer above. Can be ADO or EF.
So, any call can be up to 4 layers of injection. I see benefit in this, as each part can be isolated and tested. In some cases, the business layers can just "pass through" to the data layer (e.g., GetClientByID(int id) has little logic), but are there in case rules change. I feel the injections for the data layer abstract away any auto-generated entities from the web services. Luckily, in my case currently, it shares a common project, but who knows if this stays that way.
Is this too much? Thanks.
Your question is highly subjective, but I will try to answer it anyway.
You are breaking your application into logical tiers that can each be unit tested. This is generally a good thing. Different abstraction points or interfaces mean that you can easily swap the logic if you need to down the road, which makes the application more extensible and maintainable.
Is it too much?
That really depends on several factors - deadlines, budget, the life expectancy of the project, etc. The more layers you need to build, the bigger the upfront investment and the more layers you need to maintain later. But the abstractions make it easier to swap business logic - which often makes it worth the upfront cost.
But is it too much for your DI container to handle? No. Keep in mind the purpose of DI is to simplify application complexity. The more layers and services you have, the more it makes sense to use DI. DI makes it so your application layers and services don't depend directly on each other so they can be replaced without too much effort. Also, if you use a Composition Root pattern and use constructor injection, DI generally has very low overhead so performance is almost never a factor.
Related
So I started reading about Clean Architecture, and so far I can see that the whole purpose of an architectural design like this is to separate concerns, parts of the application in order to make bigger future changes like switching to a different ORM easier.
From the articles I've read, it seems like the WebAPI project of the solution should have a reference to the Application and Infrastructure layers. I get why we need a reference to the Application layer, but what about Infrastructure?
This is making the WebAPI layer, which is essentially the entry point of the application, depend on the Infrastructure layer, which leads to a tightly coupled situation (at least in my head)
Can you please help me understand the reason behind this? What happens if you make changes to the infrastructure layer. In this case it would possibly break the whole application, because the entry point is broken, wouldn't it?
By general rule of thumb, all of the registration of the modules (not services) is done in the presentation layer.
For example:
// Add services to the container.
builder.Services.AddApplicationServices();
builder.Services.AddInfrastructureServices(builder.Configuration);
builder.Services.AddWebUIServices();
This is done because the presentation has its own extra layers, like logging, configuration, error handling and more that should be registered in the presentation layer because it depends on the asp framework itself rather than any other third party libraries.
So technically you don't want your infrastructure to be dependant on the fact that its an asp dotnet core project and thats why we try to register the framework related things inside of the presentation layer.
If you really want to you can make it so the infrastructure is registered in the application service registration and that is fine but it kills the whole idea that all the modules would be registered in one single place.
Additionally, you sometimes have infrastructure implementations that are only dependant on the web api itself. For example, lets say you have an interface called ICurrentUserService, one of its implementations would be HttpCurrentUserService when you are sending a request and this service would be in the presentation layer because IHttpContextAccessor is only registered on the presentation layer. Alternatively you can have a different implementation of the service when you aren't coming from an HTTP request and that service would be registered in the infrastructure layer.
Here is an example of this service I am talking about:
https://github.com/jasontaylordev/CleanArchitecture/blob/main/src/WebUI/Services/CurrentUserService.cs
What happens if you make changes to the infrastructure layer. In this case
it would possibly break the whole application, because the entry point is broken, wouldn't it?
Doesn't really make sense, if the infrastructure won't compile obviously the project doesn't work. The infrastructure only holds implementation and if some of these implementations are broken it doesn't mean the whole app dies.
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.
I've been reading a lot about dependency injection and the service locator (anti-?) pattern - a lot of it on StackOverflow (thanks guys :). I have a question about how this pattern works when it's within a n-layer architecture.
I've seen a lot of blog posts where they describe injecting a IDataAccess component into the business objects. E.g.
public class Address
{
IDataAccess _dataAccess;
public Address(IDataAccess dataAccess)
{
this._dataAccess = dataAccess;
}
}
However, I was under the impression that in an n-layer architecture, the UI layer should not need to have any knowledge of the data access layer... or even know that there /is/ a data access layer! If DI requires exposing the IDataAccess interface in the constructors of the BusinessObjects, this then exposes to the UI the fact that the Business Layer uses a data access layer under the hood - something the UI doesn't need to know or care about surely?
So, my fundamental question is: Does DI require that I expose all my lower layer interfaces to all upper layers and is this a good or a bad thing?
Thanks
Edit: To clarify (after a few comments), I know my business object should be ignorant of the which specific implementation of which IDataAccess it uses (hence the Dependency being injected in the constructor) but I thought that the layers above the BO should not know that the Business Object even requires a dependency on a DAL.
This is really a fairly complex topic, and there are many ways of doing an n-tier architecture. No one way is "the right way", and how you do it depends on your needs as much as it does your personal preferences.
Dependency Injection is about managing dependencies. If your object should be unaware of any dependency, then you would not write your objet in the way you mentioned. You would instead have some other service or method that would populate the data in an agnostic way. Data doesn't mean "Database" either. So IDataAccess could mean it comes from a database, or it comes from a network socket or it comes from a file on disk. The whole point here is that Address does not choose what dependencies it creates. This is done through configuration at the composition root.
Things need data, otherwise your app is probably useless. Making your Address object load itself, however, may not be the best way to go about things. A better approach may be with a factory class or service method.
I think the answer is rather simple. Your bottom layers (interface, bll, dal, entities) are just a bunch of libraries. It is up to the client to decide which libraries to be used and it will increase client's flexibility. Moreover they are libraries, so any application-related configurations (connection strings, data caching, etc) lies on the client. Those configuration itself, sometimes also need to be injected and included into Composition Root.
However, if you want to has an uniform logic and not client's flexibility, you can choose web/app services as an additional layer.
1st Layer Entities
2nd Layer Interface
3rd Layer BLL & DAL
4th Layer Web/App Services
5th Layer UI
This way, your composition root exists in one layer (4th). And add your UI just need to add service reference to 4th layer (or 1st if needed). However, this implies the same Mark Seeman's article again, layering is worth the mapping. I assume that you can change the app/web service to Composition Root.
Moreover, this (app/web service) design has pros/cons. Pros:
Your app is encapsulated
Your app is being bridged by app/web services. It is guranteed that your UI don't know the DataAccess, thus fulfill your requirements.
Your app is secured
Simply said, having UI need to access app service is a huge gain in security aspect.
Access Portability
Now your app can be accessed everywhere. It can be connected by 3rd party app (other web) without has relying on dlls.
Cons:
Overhead cost during service call
Authentication, network connection, etc, will cause overhead during webservice call. I'm inexperienced for the performance impact but it should be enough for high traffic app.
Inflexibility of client
Client now need to access BLL/Services by using services instead of normal objects.
More Service for Different Type of Client
Now you need to provide more service than needed. Such as WebRequestRetriever, MobileRequestRetriever instead of accessing to a mere IRequestRetriever and let the composition root wire up the rest.
Apologize if this answer boarden the topic (just realized after finished).
IMHO:
It depends on who does the injection !-
It seems you need to/expect to have an MVC or MVP architecture to be in place, where a controller or Presenter does the job of translating the UI calls to business objects ,back and forth -
Creating concrete implementations of IDataAccess, Sending it to Address class.
So that the UI is totally unaware of who is providing the data it needs, and it provides you the expected scalability.
Thanks
Tarriq
I'm using the Unity IoC framework and have a Bootstrapper.cs class in my host MVC layer to register all components. However in my architecture I have a 'services' layer below the MVC layer, that too uses DI and there are repository interfaces injected into it (repository interfaces are not used in the MVC layer - it has the services layer Interface injected into its Controllers).
So my question is the following: can I still register the repository interface to it's concrete type in the MVC/UI layer for the entire app, or do I add another reference to Unity and create another Bootstrapper.cs class in my 'services' layer to define Interface types for that that specific layer uses?
Even if the answer is I can register the Interface in the UI layer, I'd still like to know the common practice too. The thing I don't like about registering that type in the MVC/UI layer is I would have to add a reference to the Repository layer just to make the registration, even know it is not used in that layer. It's used in the services layer.
Thanks!
Each application should have its own Composition Root, the place where you configure the application (see this answer for details).
It depends on the context, but generally speaking, if you split your container configuration among the layers you are going to make decisions about the configuration of your layers too close to the layers and you'are likely to lose the general view.
For example, in one of your business logic layers you'are registering a service:
container.RegisterType<ISercice1, MyImplementation1>(new PerThreadLifetime())
But when using that layer in a web application you could decide that a PerSession or PerRequest lifetime would be better lifetimes. This decisions should be in only one place and not spread through the layers.
I turn your question on its head.
If you add a reference to Unity in your class libraries, you would have added dependencies to the framework you are using. That is quite the opposite of what you are trying to achieve.
The only adaptation your classes should need is to support constructors or using public properties - on interfaces. That's it!
So your application entry point should do all the 'bootstrapping'.
Note that a entry point could be different applications, as well as different test projects. They could have different configurations and mocking scenarios.
If your bootstrap.cs gets large, you could split it up into smaller parts for readability reasons. But I reject the idea of classes having any knowledge about the fact that they are being bootstrapped/moqed/injected and by what.
Consider re-use. Your current libraries is using Unity. They may be used in a project using StructureMap. Or why not Ninject.
In short, yes it is possible to keep the configuration at the top of the process or localized to each module. However, all dependencies must be resolved for the entire object graph in the process.
Localizing the configuration by keeping it in each module (assembly) is often a good idea because you are allowing your service layer to take responsibility for its own configuration. My answer to this question, IMHO, is a good practice.
Yes, application should have one composition root at entry point. But it can be a good practice to keep registrations of a classes inside a layer where they are implemented. Then pull these registrations from layers at composition root, registering implementations layer by layer. This is why:
Registration within layer can be redefined in other place, for
example at entry point. Most of IoC libraries work in such a way
that registration done later erases the registration done earlier.
So registration within layer defines just a default behavior which
can be easily overridden.
You don't need to reference IoC library in all your projects\layers, even if you have registrations defined inside these
layers. A very simple set of wrapper classes will allow you to
abstract away from IoC specifics anywhere except your entry point.
When your application has several entry points, reusable registration will greatly help to prevent repeating the same
registration. This copy\paste is always bad. And applications have
several entry points quite often. For example, consider the scenario
of cross-platform application having a separate entry point for
every platform it targets. Or business logic reused in web site and
in background process.
With reusable registration, you can build a very effective testing system. You will be able to run a whole layer from tests,
mock whole layers in automated way, and do it very effectively,
minimizing efforts on writing tests.
See my blog article illustrating these points in more detail, with a working sample.
I am wondering about the long term advantages (if any) of layering my web app by separating my business logic and data from my web forms. (ie a form, business logic, data not in the same file, but each in it's own class in another folder by itself or combined with other like classes). I like to make everything as modular as possible and to do so efficiently it seems that keeping all the code in one file - in the web form makes organization and reuse much easier. There are certain functions that are used across the site like managing connections that would be in their own classes and files. I am pretty new to c#, sorry if I am messing up the terminology.
Thanks
The separation of code into layers brings benefits beyond just C# language.
If your data access code is kept in a separate layer, it will be easy to adjust it to work with a different database. Database-specific code will be encapsulated in this layer while clients will work with database-agnostic interfaces. Therefore changes here will not affect the business layer implementation.
If your business logic is kept in one place, you will be able to offer its services to other applications, for example, to serve requests made via web services.
If your code is clean and well structured, the maintenance efforts will be kept lower. Whenever you need to change something, you'll know where to find the responsible code, what to change and how to assure the change will not affect the rest of the code.
As for ASP.NET, not following the separation of concerns has caused many projects to turn into a giant code blurb - presentation code performs business decisions, code-behind talks directly to the database whenever no suitable business method exists, database gets written to from many places, dataflow is following multiple paths which are difficult to trace, changes in one path not introduced to all of them will break integrity and cause data corruption => Result? Almost unmaintainable code black box where any change requires more and more effort until it stalls - project is "finished". Technical bankruptcy.
We usually layer our application as follows (each of the layer is in a separate project of the solution and consequently in a separate Dll:
What I would always go for (first) is to have a layered application
Presentation Layer (JUST UI and databinding logic)
Interface Layer to
the Business Layer (defining the
contracts for accessing the BL)
Business Layer implementation (the
actual logic, data validation etc...)
Interface Layer to the Data Access
Layer (defining the contracts for
accessing the DAL)
Data Access Layer
implementation
You can then use some factory for retrieving the corresponding objects. I would take a look at some library, possibly using dependency injection like Spring.Net or Microsoft Unity from the MS patterns and practices.
The advantages are the following:
separation of logic where it belongs to
no business logic in the UI (developers have to pay attention to this)
all of your applications look the same and consequently developers knowing this architecture will immediately know where to search for the corresponding logic
exchangeable DAL. The interfaces define the contracts for accessing the corresponding layer.
Unit testing becomes easier, just focusing on the BL logic and DAL
Your application could have many entry points (web interface, Winforms client, webservice). All of them can reference the same business logic (and DAL).
...
Just could not live without that..