创建整体IoC容器

时间:2015-04-01 07:23:27

标签: c# ioc-container bootstrapper

我在项目中使用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

1 个答案:

答案 0 :(得分:1)

假设有3个子程序集,CommonModuleAModuleB

  • CommonICommon界面和您的ISimpleInjectorRegistration界面。
  • ModuleA CommonA ICommon实施IOne及其独立注册(OneITwoTwoModuleB
  • CommonB ICommon IThree实施Three及其注册(IFourFourModuleApublic 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)); } } )< / LI>

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

现在,在Main模块中,您可能会这样做:

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将是ICommon的实例,而CommonB将是包含单个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将包含{{1}}和{{1}}个实例。

关键是,在注册依赖项时应该保持简单。只有一个地方是理想的,但如果你有独立的模块,每个模块都不知道彼此,那么主要的&#39;谁知道这两个模块都应该正确配置注册。