I use IoC container in my project, but my project contains many submodules. And I would like use one base IoC module. Example: I have two interfaces in submodule A It is IOne and ITwo interfaces
public interface ITwo
{
// some code
}
public interface IOne
{
// some code
}
And my SimpleInjectorRegisterTypes class
public class SimpleInjectorRegisterTypes : ISimpleInjectorRegistration
{
public void Register(Container container)
{
container.RegisterSingle<ITwo, Two>();
container.RegisterSingle<IOne, One>();
}
}
And main class, where I use my logic
private static IOne _one;
private static ITwo _two;
static void Main(string[] args)
{
Container container = new Container();
new SimpleInjectorRegisterTypes().Register(container);
_one= container.GetInstance<IOne>();
_two= container.GetInstance<ITwo>();
}
It is good, but i have submodule B where I have interfaces IThree and TFour and also SimpleInjectorRegisterTypes and main class. How to write a general IoC container for all my submodules? P.S. For IoC I use bootstrapper
Assume that there are 3 sub assemblies say, Common, ModuleA and ModuleB.
Common has ICommon interface and your ISimpleInjectorRegistration interface.ModuleA has CommonA implements ICommon, and its independent registrations(IOne:One, ITwo:Two)ModuleB has CommonB implements ICommon, and its registrations(IThree:Three, IFour:Four)ModuleA register like this:
public class RegistrationA : ISimpleInjectorRegistration
{
public void Register(Container container)
{
container.Register<IOne, One>();
container.Register<ITwo, Two>();
container.Register<ICommon, CommonA>();
container.RegisterAll<ICommon>(typeof(CommonA));
}
}
And ModuleB register like this:
public class RegistrationB : ISimpleInjectorRegistration
{
public void Register(Container container)
{
container.Register<IThree, Three>();
container.Register<IFour, Four>();
container.Register<ICommon, CommonB>();
container.RegisterAll<ICommon>(typeof (CommonB));
}
}
Now, in the Main module you might do like this:
var container = new Container();
new ModuleA.RegistrationA().Register(container);
new ModuleB.RegistrationB().Register(container);
container.Verify();
But it fails on the ModuleB registration, because ICommon was duplicated in both registrations.
You can avoid duplicated registration and force to replace to latest one by using Options.AllowOverridingRegistrations:
var container2 = new Container();
container2.Options.AllowOverridingRegistrations = true;
new ModuleA.Registration().Register(container2);
new ModuleB.Registration().Register(container2);
container2.Options.AllowOverridingRegistrations = false;
container2.Verify();
var commonInstance2 = container2.GetInstance<ICommon>();
var commonInstances2 = container2.GetAllInstances<ICommon>();
As a result, commonInstance2 will be an instance of CommonB and commonInstances2 will be a sequence of ICommon that contains single CommonB instance.
You might want to get CommonA as a ICommon. Or get all implementations of ICommon as a IEnumerable<ICommon>:
var container3 = new Container();
container3.Options.AllowOverridingRegistrations = true;
new ModuleA.Registration().Register(container3);
new ModuleB.Registration().Register(container3);
// you can choose which ICommon should be registered.
container3.Register<ICommon, ModuleA.CommonA>();
// or collect all implementation of ICommon
// (of course using Assembly.GetTypes() is better solution)
container3.RegisterAll<ICommon>(typeof (ModuleA.CommonA), typeof (ModuleB.CommonB));
container3.Options.AllowOverridingRegistrations = false;
container3.Verify();
var commonInstance3 = container3.GetInstance<ICommon>();
var commonInstances3 = container3.GetAllInstances<ICommon>();
As a result, commonInstance3 will be the CommonA instance and commonInstances3 will contain both CommonA and CommonB instances.
The point is, you should keep simple when register dependencies. Only one place will be ideal, but if you have independent modules and each modules are not aware of each others, the 'Main' who knows both modules should configure the registrations correctly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With