使用.AsFactory()确定运行时类型

时间:2014-07-29 11:11:10

标签: c# castle-windsor

在这里阅读完问题后;并且试图按照http://docs.castleproject.org/(X(1)S(0w0clnf021ee0445lol02255))/Default.aspx?Page=Typed-Factory-Facility-interface-based-factories&NS=Windsor&AspxAutoDetectCookieSupport=1中提供的说明操作,我必须在某个地方错过链接。

总结我试图做的事情:

我有一个工厂界面:

public interface IFacilityTypeDescriptionBuilderFactory
{
    IFacilityTypeDescriptionBuilder CreateFacilityTypeDescriptionBuilder(Facility facility);
}

这家工厂的目的是;根据提供的Facility的特定业务规则和属性值,将返回不同的类型。它显然是IFacilityTypeDescriptionBuilder类型,但具体类型将由工厂确定(但不是由它实例化)。

最直接的实现方法是,注册IFacilityTypeDescriptionBuilderFactory服务,执行.ImplementedBy然后让工厂实例化返回的对象。但是这样做,我将被迫使用/ reference /依赖服务定位器,所以我宁愿不这样做。

根据上述帖子;通过使用ITypedFactoryComponentSelector,我应该能够实现我想要做的事情 - 并指示Windsor做什么。不需要IFacilityTypeDescriptionBuilderFactory的具体实现。

以下是我目前所做的事情:

        args.Container.AddFacility<TypedFactoryFacility>();

        args.Container.Register(
            Component.For<IFacilityTypeDescriptionBuilderFactory>()
                     .AsFactory()
            );

        args.Container.Register(
            Component.For<ITypedFactoryComponentSelector>()
                     .ImplementedBy<FacilityTypeDescriptionBuilderComponentSelector>()
            );

然后是我的ComponentSelector:

public class FacilityTypeDescriptionBuilderComponentSelector : DefaultTypedFactoryComponentSelector
{
    protected override System.Type GetComponentType(System.Reflection.MethodInfo method, object[] arguments)
    {
        if (method.Name == "CreateFacilityTypeDescriptionBuilder" && arguments.Length == 1 && arguments[0] is Facility)
        {
            var facility = arguments[0] as Facility;
            switch (facility.FacilityTypeId)
            {
                case 1:
                    return typeof (RestaurantFacilityTypeDescriptionBuilder);
                default:
                    return typeof (EmptyFacilityTypeDescriptionBuilder);
            }
        }

        return base.GetComponentType(method, arguments);
    }
}

有了所有这些,我现在试图断言所有内容都正确连接。而事实并非如此;在这个例子中,“b”最终为NULL。

        var f = new Facility();
        f.FacilityTypeId = 1;
        var b = args.Container.Resolve<IFacilityTypeDescriptionBuilderFactory>().CreateFacilityTypeDescriptionBuilder(f);
        Assert.IsNotNull(b as RestaurantFacilityTypeDescriptionBuilder, "b");

从我可以确定的结果来看,ComponentSelector永远不会被调用 - 或者至少不会像我期望的那样被调用。我得到的错误是:

找不到支持服务XYZ.Common.Builders.IFacilityTypeDescriptionBuilder的组件

所以基本上Windsor意识到它必须从.CreateFacilityTypeDescriptionBuilder(f)方法调用返回IFacilityTypeDescriptionBuilder - 它只是不知道如何。

有人能指出我,我在这里缺少什么?

1 个答案:

答案 0 :(得分:2)

你需要

.AsFactory(f => f.SelectedWith<FacilityTypeDescriptionBuilderComponentSelector>())