如何在Castle Windsor的依赖关系图中进一步指定服务覆盖?

时间:2017-10-11 09:16:03

标签: c# dependency-injection inversion-of-control castle-windsor

这是我的方案的简化。

我有一些接口IFooIBarIBaz及其实施FooBarBaz

Foo取决于IBarBar取决于IBaz,因此依赖关系图如下所示:

   Foo 
    |
   Bar
    |
   Baz

My 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

我尝试使用SpecialBaz api:

命名ServiceOverride
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有可能这样做,我该如何连线?

1 个答案:

答案 0 :(得分:2)

答案是 - Castle Windsor可以。每个DI容器都可以。我将为您提供一条规则来记住您可以解决大多数依赖性问题。

回答。

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

您需要在一点一次间接)更改图表,但不知何故,您需要在运行时遍历依赖图看看你的Baz是否被请求Foo。所以你需要一个某种工厂(抽象的东西)。

您有两个选项,具体取决于一个问题的答案:

我的更改是否依赖于静态或动态条件?

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

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

  

当我的依赖图以Foo开头时,我想用它而不是旧的Baz。

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

您可以使用Factory方法或Typed Factory Componend Selector实现此目的。我为您提供了工厂方法的示例:

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;
        }
    }
}}
相关问题