I am trying to setup dependency injection in my ASP.NET MVC 5 app using Unity.Mvc. I followed this tutorial which explains that the class UnityConfig
has a method called RegisterTypes
which allows me to register my type into the container.
However, I am using Area in my project. some of my Areas need to be able to also register types into the container. These types in my area will only be used by my area but still need to be registered.
How can I register-types into my IoC container directly from my area?
You can create a separate class that inherits from UnityContainerExtension
and place it in your area, like this:
public class MyAreaContainerExtension : UnityContainerExtension
{
protected override void Initialize()
{
Container.RegisterType<IDoesSomething, DoesSomething>();
}
}
Then in your startup,
container.AddNewExtension<MyAreaContainerExtension>();
Or if your extension has constructor parameters you pass to it, like configuration data it needs or instances it should use, you can create an instance of the extension and then do
container.AddExtension(theExtensionInstanceICreated);
It's a nice practice because it allows you to keep component registration closer to the classes being registered instead of having one gigantic file with dozens or even a hundred or more registrations.
Another benefit of this approach is that as component registrations become complicated you can write unit tests for these extensions that add the extension to a container and then resolve objects from the container.
You could have other components which must be registered in order for the types registered in this extension to work, but you don't want to duplicate the registrations in your extension. In that case you could make it explicit by specifying what types must already be registered, something like this:
public class MyAreaContainerExtension : UnityContainerExtension
{
protected override void Initialize()
{
AssertRequiredRegistrations();
Container.RegisterType<IDoesSomething, DoesSomething>();
}
private void AssertRequiredRegistrations()
{
AssertRequiredRegistration(typeof(ISomeOtherType));
}
private void AssertRequiredRegistration(Type type)
{
if(!Container.IsRegistered(type))
throw new Exception($"Type {type.FullName} must be registered with the container.");
}
}