gpt4 book ai didi

c# - 创建整体 IoC 容器

转载 作者:行者123 更新时间:2023-11-30 17:44:36 25 4
gpt4 key购买 nike

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

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,其中我有接口(interface) IThree 和 TFour还有 SimpleInjectorRegisterTypes 和主类。如何为我所有的子模块编写一个通用的 IoC 容器?附言对于 IoC,我使用 bootstrapper

最佳答案

假设有 3 个子程序集,比如 Common , ModuleAModuleB .

  • CommonICommon界面和你的ISimpleInjectorRegistration界面。
  • ModuleACommonA工具 ICommon , 及其独立注册( IOne : One , ITwo : Two )
  • ModuleBCommonB工具 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将是 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将同时包含 CommonACommonB实例。

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

关于c# - 创建整体 IoC 容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29385073/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com