解决温莎城堡中的依赖项时如何将一种类型转换为另一种类型

时间:2018-08-21 12:49:13

标签: c# castle-windsor

我正在尝试实现一个工厂类来帮助我实例化一个类FooBar

FooBar看起来像这样:

public class BarConsumer
{
    BarConsumer(IEnumerable<Bar>, IWibble wibbles)
    {
       ...
    }
}

我的工厂看起来像这样:

interface IBarConsumerFactory
{
    BarConsumer MakeBarConsumerFromFoo(Foo)
}

IWibble被Castle.Windsor满意。我的IEnumerable<Bar>可以来自Foo的单个实例。我有一个BarConsumerFactory类,它是由BarConsumer组成的Foo。但是不幸的是,要将Foo变成IEnumerable<Bar>,它需要一些依赖项(IFillangie)。所有这些依赖项都已在Castle.Windsor中注册。

目前,我有这个:

interface IBarConsumerTypeFactory
{
    BarConsumer MakeBarConsumer(IEnumerable<Bar> bars)
}

class BarConsumerFactory : IBarConsumerFactory
{
    BarConsumerFactory(
       IFillangie fillangie, 
       IBarConsumerTypeFactory barConsumerTypeFactory)
    {
       ...
    }

    BarConsumer MakeBarConsumerFromFoo(Foo foo)
    {
        //do some processing to create "processedFoo"
        ...

        return _barConsumerTypeFactory.MakeBarConsumer(
            _fillangie.FinalStep(processedFoo));
    }
}

因此IBarConsumerTypeFactory已向AsFactory()注册,并直接匹配构造函数。

所以,这可行,但是非常难看。

有什么方法可以放下IBarConsumerTypeFactory,并简单地向Castle.Windsor展示如何使用FooIEnumerable<Bar>转换为BarConsumerFactory(然后是我猜叫FooBarConverter吗?)

3 个答案:

答案 0 :(得分:0)

我相信您可以通过以下方式注册自定义工厂:

key

并完全删除

<Tab key={tab} selectTabHandler={tab => props.selectTabHandler(tab)} selectedTab={props.selectedTab} tab={tab} />

行。

通过这种方式,消费者仍然可以依靠Component.For<IBarConsumerFactory>().ImplementedBy<BarConsumerFactory>().LifestyleTransient(),但温莎城堡将在内部通过Component.For<IBarConsumerFactory>().AsFactory()

答案 1 :(得分:0)

将有关将Foo处理为IEnumerable的代码重新提交给设施,并在windsor中进行注册,设施的文档位于https://github.com/castleproject/Windsor/blob/master/docs/facilities.md

答案 2 :(得分:0)

如果您不想像描述的here那样实现抽象工厂,则可以使用自定义的ITypedFactoryComponentSelector

public class BarConsumerFactoryConverter : DefaultTypedFactoryComponentSelector
{
    private IFillangie _fillangie;

    public BarConsumerFactoryConverter(IFillangie fillangie)
    {
        _fillangie = fillangie;
    }

    protected override Arguments GetArguments(MethodInfo method, object[] arguments)
    {
        if (arguments == null)
            return null;

        Arguments argumentMap = new Arguments();
        ParameterInfo[] parameters = method.GetParameters();

        for (int i = 0; i < parameters.Length; i++)
        {
            if (parameters[i].ParameterType == typeof(Test))
                argumentMap.Add(typeof(IEnumerable<IBar>), _fillangie.FinalStep((Test) arguments[i]));
            else
                argumentMap.Add(parameters[i].Name, arguments[i]);
        }

        return argumentMap;
    }
}

BarConsumerFactoryConverter也必须向您的IWindsorContainer注册:

container.Register(Component.For<BarConsumerFactoryConverter, ITypedFactoryComponentSelector>());

最后,您必须告诉工厂将BarConsumerFactoryConverter用作其组件选择器:

container.Register(Component.For<IBarConsumerFactory>().AsFactory(f => f.SelectedWith<BarConsumerFactoryConverter>()));