假设我有两个由 CaSTLe Windsor 实例化的类,每个类都依赖于同一个接口(interface):
FooRepo
→ IApiClient
BarRepo
→ IApiClient
在这种情况下,
IApiClient
由一个类 GenericApiClient
实现,该类知道如何与任何 API 通信。但是,我想创建传递不同配置值(通过 GenericApiClient
公开)的 IApiClientConfiguration
的不同实例,以便 FooRepo
与 Foo API 端点对话,而 BarRepo
与 Bar API 端点对话:FooRepo
→ IApiClient (GenericApiClient)
→ IApiClientConfiguration (FooClientConfiguration)
BarRepo
→ IApiClient (GenericApiClient)
→ IApiClientConfiguration (BarClientConfiguration)
这是我迄今为止尝试过的:
container = new WindsorContainer();
container.Register(
Component.For<HomeController>().LifeStyle.Transient,
Component.For<FooRepo>()
.LifeStyle.Transient,
Component.For<BarRepo>()
//.DependsOn(Dependency.OnComponent<IApiClientConfiguration, BarClientConfiguration>()) // this does nothing cause the client config is not a direct dependency :(
.LifeStyle.Transient,
Component.For<IApiClient>()
.ImplementedBy<GenericApiClient>()
//.DependsOn(Dependency.OnComponent<IApiClientConfiguration, BarClientConfiguration>()) // this overrides for both FooRepo and BarRepo :(
.LifeStyle.Transient,
Component.For<IApiClientConfiguration>()
.ImplementedBy<FooClientConfiguration>()
.LifeStyle.Transient,
Component.For<IApiClientConfiguration>()
.ImplementedBy<BarClientConfiguration>()
.LifeStyle.Transient);
我无法弄清楚如何获取
FooRepo
以获取使用 GenericApiClient
配置的 FooClientConfiguration
实例,而 BarRepo
获取 BarClientConfiguration
:FooClientConfiguration
因为这是首先注册的 IApiClient
覆盖 DependsOn(...)
的配置,但这适用于 FooRepo
和 BarRepo
DependsOn(...)
上使用 BarRepo
,它没有效果 (如果上述问题不清楚,我有一个最小的工作示例 here )
有什么方法可以配置温莎城堡来做我想做的事吗?有什么方法可以更好地构建我的代码,这样我就不会遇到这个问题吗?
最佳答案
container.Register(
Component.For<IApiClientConfiguration>()
.ImplementedBy<FooClientConfiguration>()
.Named("FooConfiguration")
.LifestyleTransient(),
Component.For<IApiClientConfiguration>()
.ImplementedBy<BarClientConfiguration>()
.Named("BarConfiguration")
.LifestyleTransient(),
Component.For<IApiClient, GenericApiClient>()
.Named("FooClient")
.DependsOn(Dependency.OnComponent(
typeof(IApiClientConfiguration), "FooConfiguration")),
Component.For<IApiClient, GenericApiClient>()
.Named("BarClient")
.DependsOn(Dependency.OnComponent(
typeof(IApiClientConfiguration), "BarConfiguration")),
Component.For<FooRepo>()
.DependsOn(Dependency.OnComponent(typeof(IApiClient), "FooClient")),
Component.For<BarRepo>()
.DependsOn(Dependency.OnComponent(typeof(IApiClient), "BarClient"))
);
它不漂亮。并且可能有一种方法可以稍微简化语法。温莎通常提供几种不同的方式来做所有事情。
您正在定义
GenericApiClient
的两个不同实现,并且为每个实现指定要使用的配置。然后,在注册 FooRepo
和 BarRepo
时,您要为它们中的每一个指定要使用的 IApiClient
的命名实现。如果一个或另一个是默认值,那么您可以使用
IsDefault()
指示它并且只命名另一个。如果您为不同的实现组编写单独的安装程序,甚至只是同一安装程序中的方法,也可以更容易遵循,例如RegisterFooDependencies(IWindsorContainer container)
{
container.Register(
Component.For<IApiClientConfiguration>()
.ImplementedBy<FooClientConfiguration>()
.Named("FooConfiguration")
.LifestyleTransient(),
Component.For<IApiClient, GenericApiClient>()
.Named("FooClient")
.DependsOn(Dependency.OnComponent(
typeof(IApiClientConfiguration), "FooConfiguration")),
Component.For<FooRepo>()
.DependsOn(Dependency.OnComponent(typeof(IApiClient), "FooClient"))
);
}
关于c# - 覆盖为嵌套/传递依赖项注入(inject)的组件实现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38213376/