我们尝试将LightCore集成为Metadata- / ORM-Framework中的默认服务定位器。因此,我们喜欢框架内的一些默认注册,即Framework-User(= Application Developer)可以通过他自己的实现以某种方式“否决”(如果他喜欢这样做)。如何使用LightCore IoC容器或其他IoC容器来完成这项工作?
我们尝试了什么:
var builder = new ContainerBuilder();
builder.Register<Foo>().ControlledBy<SingletonLifecycle>();
builder.Register<Foo, Foo2>().ControlledBy<SingletonLifecycle>();
var container = builder.Build();
var foo = container.Resolve<Foo>();
我们注册了两个类作为Foo的合同。使用上面的代码,我们总是得到第一个(Foo的实例)返回。所以没有在这里推翻。顺便说一句:我们想得到一个Foo2的实例。
我们将其从使用具体类更改为使用接口:
var builder = new ContainerBuilder();
builder.Register<IFoo, Foo>().ControlledBy<SingletonLifecycle>();
builder.Register<IFoo, Foo2>().ControlledBy<SingletonLifecycle>();
var container = builder.Build();
var foo = container.Resolve<IFoo>();
有了这个,我们在Resolve&lt;&gt;()中得到一个解决异常,告诉我找不到注册。如果我们删除第二个“Register()”语句,它将以我们获取Foo实例的方式工作。
我们不确定是否错过了一些一般概念。这与其他IoC的工作原理相同吗?否决/覆盖注册的推荐方法是什么?
关于这个主题的任何帮助都会很棒 - 不仅仅适用于LightCore。
更新 我使用SimpleInjector IoC容器为上述场景设置了一些测试。使用此容器,需要在构造函数中指定AllowOverridingRegistration = true,它将按预期工作。所以看起来LightCore只是不能正确支持这个用例,但其他人也这样做。
更新 我们得到了LightCore创建者的快速回复,称LigtCore根本不支持覆盖注册。所以似乎没有办法解决这些场景注册覆盖LightCore所以我们从LightCore切换到SimpleInjector。
以下SimpleInjector配置符合我们当前的四个要求:
// Register concrete class for FooFoo
container.RegisterSingle<FooFoo>();
// Register concrete classes for Foo - Final registration should return FooFoo, not Foo
container.RegisterSingle<Foo>();
container.RegisterSingle<Foo, FooFoo>();
// Register interfaces for IFoo - Final registration should return FooFoo, not Foo
container.RegisterSingle<IFoo, Foo>();
container.RegisterSingle<IFoo, FooFoo>();
// Register list of Plugs
container.RegisterAll(new IPlug[] { new PlugA(), new PlugB() });
干杯,马克
答案 0 :(得分:1)
AFAIK所有大型DI框架(Autofac,Unity,Castle Windsor,StructureMap,Ninject)都具有覆盖注册的功能。他们中的大多数通过对同一服务类型进行多次注册来允许这种情况,并且他们选择其中一个注册作为默认注册。然而,他们选择哪个实例,每个框架都不同。虽然有些框架选择了多个注册中的第一个,但其他框架选择了最后一个注册。知道选择框架如何做到这一点很重要,因为这决定了你是应该在所有其他人之前或之后注册“覆盖”实例。
因为所有这些框架都有不同的重载分辨率,所以我决定让Simple Injector默认没有任何覆盖行为(虽然它是可配置的,正如你已经注意到的)。这使得迁移到另一个框架变得更加容易,这是Simple Injector的设计目标之一。但是,默认情况下允许注册被覆盖,也可能是配置错误的来源,这可能是耗时的追踪。由于Simple Injector应该很容易入手,因此禁止覆盖是有意义的(默认情况下)。
使用Simple Injector,当启用AllowOverridingRegistration
时,新注册确实替换了同一类型的早期注册。这与其他容器不同,后者通常保留其他注册,并允许您将所有这些注册解析为单个集合。使用Simple Injector,必须单独注册一组内容,并且可以单独覆盖。
除了简单注射器之外的所有其他容器以及我不能说的大容器。但是,我认为压倒一切对他们中的大多数都很难。