创建整体 IoC 容器
Create overall IoC container
我在项目中使用 IoC 容器,但我的项目包含许多子模块。我想使用一个基本的 IoC 模块。
例子:
我在子模块 A 中有两个接口
是 IOne 和 ITwo 接口
public interface ITwo
{
// some code
}
public interface IOne
{
// some code
}
还有我的 SimpleInjectorRegisterTypes class
public class SimpleInjectorRegisterTypes : ISimpleInjectorRegistration
{
public void Register(Container container)
{
container.RegisterSingle<ITwo, Two>();
container.RegisterSingle<IOne, One>();
}
}
和主要 class,我在其中使用我的逻辑
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>();
}
很好,但是我有子模块 B,其中我有接口 IThree 和 TFour
还有 SimpleInjectorRegisterTypes 和 main class。
如何为我所有的子模块编写一个通用的 IoC 容器?
P.S。对于 IoC,我使用 bootstrapper
假设有 3 个子程序集 Common
、ModuleA
和 ModuleB
。
Common
有 ICommon
界面和你的 ISimpleInjectorRegistration
界面。
ModuleA
有CommonA
实现ICommon
,其独立注册(IOne
:One
,ITwo
:Two
)
ModuleB
有 CommonB
实现 ICommon
,它的注册(IThree
:Three
, IFour
:Four
)
ModuleA
这样注册:
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));
}
}
和ModuleB
这样注册:
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));
}
}
现在,在主模块中,您可以这样做:
var container = new Container();
new ModuleA.RegistrationA().Register(container);
new ModuleB.RegistrationB().Register(container);
container.Verify();
但是 ModuleB
注册失败了,因为 ICommon
在两个注册中都是重复的。
使用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>();
因此,commonInstance2
将是 CommonB
的实例,而 commonInstances2
将是包含单个 CommonB
实例的 ICommon
序列。
您可能希望将 CommonA
作为 ICommon
。或者将 ICommon
的所有实现作为 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>();
因此,commonInstance3
将成为 CommonA
实例,而 commonInstances3
将同时包含 CommonA
和 CommonB
实例。
重点是,注册依赖的时候一定要简单。只有一个地方是理想的,但是如果你有独立的模块并且每个模块都不知道彼此,知道两个模块的 'Main' 应该正确配置注册。
我在项目中使用 IoC 容器,但我的项目包含许多子模块。我想使用一个基本的 IoC 模块。 例子: 我在子模块 A 中有两个接口 是 IOne 和 ITwo 接口
public interface ITwo
{
// some code
}
public interface IOne
{
// some code
}
还有我的 SimpleInjectorRegisterTypes class
public class SimpleInjectorRegisterTypes : ISimpleInjectorRegistration
{
public void Register(Container container)
{
container.RegisterSingle<ITwo, Two>();
container.RegisterSingle<IOne, One>();
}
}
和主要 class,我在其中使用我的逻辑
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>();
}
很好,但是我有子模块 B,其中我有接口 IThree 和 TFour 还有 SimpleInjectorRegisterTypes 和 main class。 如何为我所有的子模块编写一个通用的 IoC 容器? P.S。对于 IoC,我使用 bootstrapper
假设有 3 个子程序集 Common
、ModuleA
和 ModuleB
。
Common
有ICommon
界面和你的ISimpleInjectorRegistration
界面。ModuleA
有CommonA
实现ICommon
,其独立注册(IOne
:One
,ITwo
:Two
)ModuleB
有CommonB
实现ICommon
,它的注册(IThree
:Three
,IFour
:Four
)
ModuleA
这样注册:
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));
}
}
和ModuleB
这样注册:
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));
}
}
现在,在主模块中,您可以这样做:
var container = new Container();
new ModuleA.RegistrationA().Register(container);
new ModuleB.RegistrationB().Register(container);
container.Verify();
但是 ModuleB
注册失败了,因为 ICommon
在两个注册中都是重复的。
使用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>();
因此,commonInstance2
将是 CommonB
的实例,而 commonInstances2
将是包含单个 CommonB
实例的 ICommon
序列。
您可能希望将 CommonA
作为 ICommon
。或者将 ICommon
的所有实现作为 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>();
因此,commonInstance3
将成为 CommonA
实例,而 commonInstances3
将同时包含 CommonA
和 CommonB
实例。
重点是,注册依赖的时候一定要简单。只有一个地方是理想的,但是如果你有独立的模块并且每个模块都不知道彼此,知道两个模块的 'Main' 应该正确配置注册。