Castle未使用TypedFactory

时间:2017-01-11 22:08:20

标签: c# dependency-injection castle-windsor

我有一个用于工厂的接口,使用Castle的TypedFactoryFacility,它接受一个字符串。

public interface IFoo<T> {}
public interface IBar1 : IFoo<IBar1> {}
public interface IBar2 : IFoo<IBar2> {}

public class MyClass1 : IBar1 {}
public class MyClass2 : IBar2 {}

public interface IFactory<T> where T : IFoo<T>
{
    T Create(string primitive2);
}

两个MyClasses都有一个子依赖:

public class SubDependency : ISubDependency
{
    public SubDependency(string primitive1, string primitive2)
}

我想基于IFoo&lt;&gt;安装给定命名空间中的所有MyClasses但我想要IBAR接口请求和解决的实例。因此,两个接口都必须注册并解析为同一个类的同一个实例。

这是我的安装程序代码:

// register foo
container.Register(
    Classes.FromAssemblyContaining(typeof(IFoo<>))
        .InSameNamespaceAs(typeof(IFoo<>))
        .WithServiceAllInterfaces()
        .LifeStyleHybridPerWebRequestTransient());

// register factory
container.Register(
    Component.For(typeof(IFactory<>)).AsFactory()
        .LifeStyle.HybridPerWebRequestTransient());

// register sub dependency
container.Register(
    Component.For<ISubDependency>().ImplementedBy<SubDependency>()
        .LifeStyle.HybridPerWebRequestTransient()
        .DependsOn(new
        {
            primitive1 = "this resolves"
        }));

然后我像这样注册我的容器:

var container = new WindsorContainer().Install(FromAssembly.This());
container.AddFacility<TypedFactoryFacility>();

var factory = container.Resolve<IFactory<IBar1>>();
var myClass1 = factory.Create("primitive2: this does not resolve");

当我查看容器时,它显示已注册所有内容(尽管我不确定它是否已正确注册)。

我收到以下错误:

Could not resolve non-optional dependency for 'SubDependency' (SubDependency). Parameter 'primitive2' type 'System.String'

我认为容器应该将参数从工厂传递给所有具有相同名称参数的子依赖项。如何正确解析,我可以在安装程序中定义一个值并在运行时提供另一个值?

更新: 虽然我的答案可行,但我收到了一些容器警告,我不确定如何解决:

All components are potentially misconfigured (except for the IFactory): scope
Components with potential duplicated dependencies: SubDependency, TypedFactoryComponentSelector

1 个答案:

答案 0 :(得分:0)

我得到了它的工作,虽然它看起来像一个可怕的黑客,所以获得一些指导会很棒。

我改变了我的IFoo&lt;&gt;注册:

container.Register(
    Classes.FromAssemblyContaining(typeof(IFoo<>))
        .InSameNamespaceAs(typeof(IFoo<>))
        .WithServiceAllInterfaces()
        .LifeStyleHybridPerWebRequestTransient()
        .Configure(r => r.DynamicParameters((k, d) =>
        {
            var subDependency = k.Resolve<ISubDependency>(d);
            d.Add("subDepedency", subDependency); 
        })));

这有效,但我不喜欢它,我希望有更好的方法。这要求所有具有SubDependency的类作为依赖关系命名为“subDependency”,例如:

public class MyClass1 : IBar1
{
    public MyClass1(SubDependency subDependency) // <-- MUST be named that.
}

我不确定我是否已经引起了更多问题,然后用这个解决方案解决了。是否有一种更简单的方法可以将TypedFactory参数传播到所有具有该名称参数的子依赖项?