Windsor通过构造函数参数注册单例组件和Resolve

Windsor register singleton component and Resolve by passing constructor parameters

我有一个 class 带有波纹管构造函数:

Foo(FooType type)

FooType 是枚举。我这样注册 class:

container.Register(
  Component.For<IFoo>()
           .ImplementedBy<Foo>()
           .LifestyleSingleton())

我需要这个 class 的两个实例,但差异 FooType。我像下面这样解决这种类型:

IFoo foo1 = container.Resolve<IFoo>(new { type = FooType.Type1 });
IFoo foo2 = container.Resolve<IFoo>(new { type = FooType.Type2 });

foo1foo2是同一个对象吗?

答案是 ,那么,我如何才能将 Foo 注册为单例并解析它的两个不同实例 FooType?

您不能直接这样做。单例生活方式意味着你的服务只有一个实例,这就是单例的意思。

要获得多个实例,您可以将生活方式更改为瞬态(或可能是作用域)或多次注册此服务。为此,您需要一种方法来明确处理每个服务实例。

Windsor 中可以注册名称服务。

container.Register(
    Component.For<IFoo>().ImplementedBy<Foo>().LifestyleSingleton().Named("Instance1),
    Component.For<IFoo>().ImplementedBy<Foo>().LifestyleSingleton().Named("Instance2)
);

然后您可以通过调用来解析此类型:

var intsance1 = container.Resolve("Instance1");
var intsance2 = container.Resolve("Instance2");

但是因为你的服务是单例的,不可能在每次解析的时候都传递构造函数参数,它们只会被使用一次。在这种情况下,最好在注册服务时设置构造函数参数。您可以使用 DepensOn(...)

container.Register(
    Component.For<IFoo>()
             .ImplementedBy<Foo>()
             .LifestyleSingleton()
             .Named("Instance1)
             .DependsOn(new { type = FooType.Type1 }),
    Component.For<IFoo>()
             .ImplementedBy<Foo>()
             .LifestyleSingleton()
             .Named("Instance2)
             .DependsOn(new { type = FooType.Type2 })
);

我最终通过将 IFoo 转换为 IFoo<T> 并使用多个接口而不是枚举值解决了我的问题。现在我的代码是这样的:

public interface IFooType
{ }

public interface IFooType1 : IFooType
{ }

public interface IFooType2 : IFooType
{ }

public interface IFoo<T>
    where T : IFooType
{
    string FooType { get; }
}

public class Foo<T> : IFoo<T>
    where T : IFooType
{
    public string FooType
    {
        get
        {
            return typeof(T).ToString();
        }
    }
}

并注册并解析 Foo:

container.Register(Component.For(typeof(IFoo<>))
                            .ImplementedBy(typeof(Foo<>))
                            .LifestyleSingleton());

var foo1 = container.Resolve<IFoo<IFooType1>>();
var foo2 = container.Resolve<IFoo<IFooType2>>();

Console.WriteLine("foo1 : " + foo1.FooType); // return foo1: IFooType1
Console.WriteLine("foo2 : " + foo2.FooType); // return foo1: IFooType2

这种方法解决了我的问题,但我不确定这是不是唯一的方法?