'Dotnet organizing dependency injection registration and project seperation
Have a project structure where I have a couple of layers
Api
Bll
Dal
Utility
When say a order request is received by the Api there is a couple of steps that we need to take. Like:
- Validate the input
- Save the customer
- Save the order
- Validate payment
- Save final order status
All of these require different classes from the Bll And the classes inside the Bll requires classes from Dal and maybe other Bll or from Utility.
So now inside the Api I need to register the whole chain of what might be needed like
Register<IValidateService,ValidateService>()
Register<ICustomerService,CustomerService>()
Register<ICustomerDatabaseService,CustomerDatabaseService>()
Register<IUtilityService,UtilityService>();
Maybe all of the above just to get the CustomerService working, and then we need to do this for a lot more services and I will have to reference the Dal layer inside the Api layer. And in the long run I feel that everything will become really bloated. Would be good if I could just Register the CustomerService and then that will register it's dependencies by itself or something.
Maybe it is fine to have the entry level to be aware of everything?
Any ideas on how to solve this or am I overthinking things?
Thank you
Solution 1:[1]
My suggested solution for auto-registration is the following:
- Use Autofac.
- Create a public
DependencyModuleclass derived fromAutofac.Modulein yourApi,Bll,DalandUtilityprojects. - Override the
Loadmethod and register only types that are in that project. - In your startup project (
Api) use my nuget package to automatically discover and register all yourDependencyModuleclasses into the DI container.
At the end you will have something like this:
UtilityDependencyModule.cs- registers all the utility types that need to be injected.
DalDependencyModule.cs- registers all the DAL types (e.g.DbContext) that need to be injected.
BllDependencyModule.cs- registers all the BLL types that need to be injected.
ApiDependencyModule.cs- registers all the API types (if any) that need to be injected. E.g. filters, etc.- In
Program.csorStartup.csyou register only my Autofac module that will discover and register all your modules above.
See my example solution's description and implementation.
This way each injectable type registration is done in its own assembly and dependent services do not need to worry about it.
Alternative solution - uses Microsoft DI
Instead of Autofac modules you can create extensions methods for IServiceCollection type in each of your project and register the types that are in that project.
Then in your Program.cs or Startup.cs just call each extensions method.
At the end you will have something like this:
UtilityIServiceCollectionExtensions.cs- registers all the utility types that need to be injected.
DalIServiceCollectionExtensions.cs- registers all the DAL types (e.g.DbContext) that need to be injected.
BllIServiceCollectionExtensions.cs- registers all the BLL types that need to be injected.
ApiIServiceCollectionExtensions.cs- registers all the API types (if any) that need to be injected. E.g. filters, etc.- In
Program.csorStartup.cscall each of the extensions methods.
Note
Actually you can combine MS DI with Autofac so that you can enjoy the advanced features of Autofac and use specific extension methods for IServiceCollection at the same time.
In that case you should know that the order of registrations is this:
- MS DI registrations:
ConfigureServices()method - Autofac registrations:
ConfigureContainer<T>()method
All the MS DI registrations will be populated into the Autofac container.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
