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

标签 c# castle-windsor

阅读完此处的问题后;并尝试按照 http://docs.castleproject.org/(X(1)S(0w0clnf021ee0445lol02255))/Default.aspx?Page=Typed-Factory-Facility-interface-based-factories&NS=Windsor&AspxAutoDetectCookieSupport=1 中提供的说明进行操作,我一定是在某个地方缺少了一个链接。

总结一下我正在尝试做的事情:

我有一个工厂接口(interface):

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

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

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

根据上面的帖子;我应该能够通过利用 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 - 它只是不知道如何返回。

任何人都可以向我指出,我在这里缺少什么吗?

最佳答案

你需要

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

关于c# - 使用 .AsFactory() 确定运行时类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25013915/

相关文章:

c# - CaSTLe 温莎 Controller 工厂和 RenderAction

dependency-injection - 如何在多项目解决方案中使用 .net 核心依赖注入(inject)?

C#:无法检查类型是否为数组

c# - 在 Dispose() 中设置 obj = null(Nothing) 有什么意义吗?

javascript - 如何将 List<> 传递给 Javascript 并在组合框 C# 中显示

asp.net-mvc - MVC3 模型与 CaSTLe 绑定(bind)

c# - CaSTLe Windsor 中的条件解析

c# - 为什么 CaSTLe Windsor 会捕获 transient 对象?

c# - 如何将复选框映射到 MVC 模型成员?

c# - 类型 'Attribute' 在未引用的程序集中定义 - Xamarin