创建整体IoC容器

3

我在项目中使用了IoC容器,但我的项目包含许多子模块。我想使用一个基本的IoC模块。 例如: 我在子模块A中有两个接口, 它们是IOne和ITwo接口。

public interface ITwo
{
     // some code
}

public interface IOne
{
     // some code
}

我的SimpleInjectorRegisterTypes

public class SimpleInjectorRegisterTypes : ISimpleInjectorRegistration
    {
        public void Register(Container container)
        {
            container.RegisterSingle<ITwo, Two>();
            container.RegisterSingle<IOne, One>();
        }
    }

这是我的主类,我在这里使用我的逻辑

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 和主类。如何为所有子模块编写通用的 IoC 容器?
P.S. 我使用 bootstrapper 进行 IoC。


为什么要在多个地方注册依赖项?为什么不在应用程序入口点中完成所有“引导”工作呢? - L-Four
所以你有一个容器,在其中注册接口/类对,然后你有一个接口/类对,只是进行了上述注册 - 然后你仅使用所有这些来在静态类中创建两个接口的静态实例.... 这不是有点过度设计吗? - Random Dev
我有独立的模块,如果可能的话,我想创建一个总的IoC容器,该如何实现? - Taras Kovalenko
1个回答

1
假设有三个子装配件,分别为CommonModuleAModuleB
  • CommonICommon接口和您的ISimpleInjectorRegistration接口。
  • ModuleA具有实现ICommonCommonA,以及其独立注册(IOne:One,ITwo:Two)
  • ModuleB有实现ICommonCommonB,以及其注册(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 将包含 CommonACommonB 实例。
重点是,在注册依赖关系时应该保持简单。只有一个地方是理想的,但如果您拥有独立的模块且每个模块不知道彼此,则了解两个模块的 'Main' 应正确配置注册信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接