【问题标题】:Create overall IoC container创建整体 IoC 容器
【发布时间】:2015-04-01 07:23:27
【问题描述】:

我在我的项目中使用 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 容器? 附言对于 IoC,我使用 bootstrapper

【问题讨论】:

  • 为什么要在多个地方注册依赖项?为什么不在您的应用程序入口点执行所有“引导”?
  • 所以你有:一个容器,你注册你的接口/类对,然后你有一个接口/类对只是做所说的注册 - 然后你只使用所有这些来创建你的接口的两个静态实例在静态类中......这不是有点矫枉过正吗?
  • 我有独立的模块,并且我已经(如果可能的话)创建了一个整体的 IoC 容器,该怎么做?

标签: c# ioc-container bootstrapper


【解决方案1】:

假设有 3 个子程序集,例如 CommonModuleAModuleB

  • CommonICommon 接口和你的ISimpleInjectorRegistration 接口。
  • ModuleACommonA实现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&lt;ICommon&gt;

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 实例。

关键是,注册依赖项时应该保持简单。只有一个地方是理想的,但是如果您有独立的模块并且每个模块彼此不了解,则知道两个模块的“主”应该正确配置注册。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-10
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    • 2014-04-29
    • 2015-06-01
    • 2016-03-16
    • 2011-01-02
    相关资源
    最近更新 更多