我对TypedFactory Windsor工具有什么控制?

时间:2012-02-08 17:32:30

标签: castle-windsor typed-factory-facility windsor-facilities

我的同事在我们的项目中设置了Windsor TypedFactoryFacility。

我是Windsor的新手,并且不明白它是如何实现我们注册为工厂的IServiceFactory接口中的方法。当我看到一个带有类型参数T并返回T的Create方法时,我发现它可能正在调用容器的Resolve方法。

我需要Create的重载,它将Type作为参数并返回一个对象。由于容器的Resolve方法具有以下两种风格:

T Resolve<T>(string key);
object Resolve(Type service);

我认为添加Create的重载会起作用。相反,它似乎试图解析System.Object而不是Type I传入。

有没有办法让Windsor以我想要的方式实现我的Create方法?我用反射器探测了一下,但无法弄明白。

这是注册:

container.AddFacility<TypedFactoryFacility>();
        container.Register(
                Component.For<IServiceFactory>()
                        .AsFactory()
                        .LifeStyle.Transient);

和界面本身:

public interface IServiceFactory
{
    //Original Create method that works
    T Create<T>();

    //The overload that I need that throws an exception
    object Create(Type service)

    void Release(object service);
}

1 个答案:

答案 0 :(得分:0)

您要拨打serviceFactory.Create(typeof(IMyServce))而不是serviceFactory.Create<IMyService>()吗?

尝试在扩展方法中使用反射,例如

public static class ServiceFactoryExtensions
{
    public static object Create(this IServiceFactory factory, Type serviceType)
    {
        return typeof(IServiceFactory).GetMethod("Create")
            .MakeGenericMethod(serviceType).Invoke(factory, new object[]{});
    }
}

修改

此扩展方法确实适用于Castle Windsor创建的工厂。

这是我的原始测试代码,您可以将其放入VS2010控制台应用程序的Program.cs中,添加对Castle.Core和Castle.Windsor的引用,然后运行。我使用了Castle.Windsor 2.5.4

using System;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel.Registration;
using Castle.Windsor;

namespace StackOverflow9198461
{
    public static class ServiceFactoryExtensions
    {
        public static object Create(this IServiceFactory factory, Type serviceType)
        {
            return typeof(IServiceFactory).GetMethod("Create")
                .MakeGenericMethod(serviceType)
                .Invoke(factory, new object[] { });
        }
    }

    class Program
    {
        static void Main()
        {
            var container = new WindsorContainer();
            container.AddFacility<TypedFactoryFacility>();
            container.Register(Component
                .For<IServiceFactory>()
                .AsFactory());
            container.Register(Component
                .For<IMyService>()
                .ImplementedBy<MyService>()
                .LifeStyle.Singleton);
            var factory = container.Resolve<IServiceFactory>();
            var s1 = factory.Create<IMyService>();
            var s2 = factory.Create(typeof(IMyService));
            Console.WriteLine(s1.GetType().FullName);
            Console.WriteLine(s2.GetType().FullName);
            if (s1 == s2) Console.WriteLine("Success");
        }
    }

    public interface IServiceFactory
    {
        //Original Create method that works
        T Create<T>();

        ////The overload that I need that throws an exception
        //object Create(Type service)

        void Release(object service);
    }

    public class MyService : IMyService
    {
    }

    public interface IMyService
    {
    }
}