Currently, I'm working on a large project where there is a DLL (let's call it Common.DLL) that is updated frequently to contain new classes that require registration through Unity for DI. There are about 3 other applications (website, WCF service, etc.) all that reference this DLL and have their own Unity configuration file which if a new class is created in Common, all needed updated to register this new type.
Obviously, this can be a pain to manage and I'm inheriting this project so I'm thinking of ways to make this process easier. It should be noted the Common.DLL could certainly be placed into a Nuget package and distributed that way.
I'm more or less seeing if anyone knows of a good way where I update Common.DLL or Common NuGet package with a new class and the other applications update their registrations when the Common.DLL they reference changes or when the package is updated. Any feedback would be appreciated. Thanks!
Since you mention that the classes in Common are registered the same way for every application, I would create programmatic registration for all the classes in Common. Unity allows mixing programmatic with declarative configuring. So Common.dll components could be registered programmatically while application specific registrations (that might change) could be done using XML configuration.
I would place the burden of creating the registrations on the developers of Common.dll since they will know how classes should be registered and will only have to be done once (and not for every application). When there is an update all of the applications will just pick up the registration changes without changing any code.
You probably don't want Common.dll to depend directly on Unity so you might want to create a separate assembly for registrations such as Common.Ioc.Unity.dll
and in there provide a method to bootstrap Common.dll registrations. e.g.
public class RegistrationManager : IRegistrationManager
{
private IUnityContainer container;
public RegistrationManager(IUnityContainer container)
{
this.container = container;
}
public void RegisterCommon()
{
this.container.RegisterType<Common.Logger>(new ContainerControlledLifetimeManager());
}
}
You could even provide different flavors of Registration to support different containers (if that's desired).
The downside is that that is a small assembly that will also have to be referenced by the application. If there are many assemblies similar to Common.dll then it might make sense for you to think about putting all shared registrations in one assembly.
Another (stylistic) variation of the above is to implement the registrations using a container extension. For example:
public class CommonContainerExtension : UnityContainerExtension
{
protected override void Initialize()
{
Container.RegisterType<Common.Logger>(new ContainerControlledLifetimeManager());
}
}
Then in the application you could register using:
var container = new UnityContainer();
// Register Common.dll using container extension or RegistrationManager
container.AddNewExtension<CommonContainerExtension>();
// Register XML configuration for application
// Application can even overwrite Common.dll registrations from above if required
container.LoadConfiguration();