gpt4 book ai didi

c# - 如何在 CaSTLe Windsor 的依赖图中进一步指定服务覆盖?

转载 作者:行者123 更新时间:2023-11-30 23:08:12 25 4
gpt4 key购买 nike

这是我的场景的简化。

我有一些接口(interface)IFoo , IBar , 和 IBaz及其实现 Foo , BarBaz .

Foo取决于 IBarBar取决于 IBaz ,所以依赖图看起来像这样:

   Foo 
|
Bar
|
Baz

我的 Windsor 配置如下所示,一切都按预期工作:

container.Register(Component.For<IFoo>().ImplementedBy<Foo>());
container.Register(Component.For<IBar>().ImplementedBy<Bar>());
container.Register(Component.For<IBaz>().ImplementedBy<Baz>());

现在我需要介绍一个新的SpecialBaz ,我想用它代替旧的 Baz当我的依赖关系图以 Foo 开头时.该应用程序的其余部分将继续使用旧的 Baz :

      Foo           SomethingElse
| |
Bar Bar
| |
SpecialBaz Baz

我试过命名 SpecialBazServiceOverride接口(interface):

container.Register(Component.For<IBaz>().ImplementedBy<Baz>().IsDefault());
container.Register(Component.For<IBaz>().Named("special baz").ImplementedBy<SpecialBaz>());

container.Register(Component.For<IFoo>()
.ImplementedBy<Foo>()
.DependsOn(ServiceOverride.ForKey<IBaz>().Eq("special baz")));

并指定依赖关系:

container.Register(Component.For<IBaz>().ImplementedBy<Baz>().IsDefault());
container.Register(Component.For<IBaz>().ImplementedBy<SpecialBaz>());

container.Register(Component.For<IFoo>()
.ImplementedBy<Foo>()
.DependsOn(Component.For<IBaz>().ImplementedBy<SpecialBaz>()));

但这两种方法都不起作用。

这在 CaSTLe Windsor 中可行吗?我该如何连接它?

最佳答案

简短的答案是 - 温莎城堡可以。每个 DI 容器都可以。我会给你一个规则来记住你可以解决你的大部分依赖问题。

答案。

规则:每个间接点都需要一个抽象层。当您尝试在应用程序中构建依赖项解决方案时,请牢记此规则。据我所知,有两种间接方式 - 静态和动态。

您需要在一个点并且仅一次(间接)更改图,但是您需要以某种方式在运行时遍历依赖关系图查看您的 Baz 是否被要求用于 Foo 。所以您需要某种工厂(抽象事物)。

根据一个问题的答案,您有两个选项:

我的更改取决于静态还是动态条件?

例如 - 如果您依赖传入的用户数据或环境数据 - 您处于动态情况下,您需要使用 Dynamic Parameters或其他有能力的东西。

在您的情况下,您的依赖项是静态的。

and I want to use it instead of the old Baz when my dependency graph begins with a Foo.

一旦图形的开头是 Foo,特殊 Baz 的条件就永远不会改变。

您可以使用工厂方法或类型化工厂组件选择器来实现这一点。我为您提供了一个工厂方法示例:

using System;
using Castle.MicroKernel.Registration;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var container = new Castle.Windsor.WindsorContainer();
container.Register(Component.For<IFoo>().ImplementedBy<Foo>());
container.Register(Component.For<ISomethingElse>().ImplementedBy<SomethingElse>());

container.Register(Component.For<IBar>().ImplementedBy<Bar>().LifeStyle.Transient);

container.Register
(
Component
.For<IBaz>()
.UsingFactoryMethod
(
(k, c) =>
{
IBaz resolved = null;
var requestingType = c.Handler.ComponentModel.Implementation;
if (requestingType == typeof(Foo))
{
resolved = new Baz();
}
else
{
resolved = new BazSpecial();
}

return resolved;
}
).LifeStyle.Transient
);

var f = container.Resolve<IFoo>();
var se = container.Resolve<ISomethingElse>();

Console.ReadLine();
}
}
internal interface IBar
{
}

internal interface IBaz
{
}

internal interface IFoo
{
}

interface ISomethingElse
{

}


internal class Bar : IBar
{
private readonly IBaz baz;

public Bar(IBaz baz)
{
this.baz = baz;
}

}

internal class Baz : IBaz
{
}

internal class BazSpecial : IBaz
{
}

internal class Foo : IFoo
{
private readonly IBar bar;

public Foo(IBar bar)
{
this.bar = bar;
}
}

internal class SomethingElse : ISomethingElse
{
private readonly IBar bar;

public SomethingElse(IBar bar)
{


this.bar = bar;
}
}
}}

关于c# - 如何在 CaSTLe Windsor 的依赖图中进一步指定服务覆盖?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46684378/

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