Какой контроль у меня над инструментами TypedFactory Windsor? - PullRequest
0 голосов
/ 08 февраля 2012

Мой коллега настроил Windsor TypedFactoryFacility в нашем проекте.

Я новичок в Windsor и не понимаю, как он реализует методы интерфейса IServiceFactory, который мы регистрируем как фабрику. Когда я увидел метод Create, который принимает параметр типа T и возвращает T, я подумал, что он, вероятно, вызывает метод Resolve контейнера под прикрытием.

Мне нужна перегрузка Create, которая принимает Type в качестве параметра и возвращает объект. Так как метод Resolve контейнера имеет оба эти вкуса:

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

Я думал, что добавление перегрузки Create будет работать. Вместо этого он пытается разрешить System.Object вместо типа I, который передается.

Есть ли способ заставить Виндзор реализовать мой метод 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 голосов
/ 23 февраля 2012

Вы хотите назвать что-то вроде 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[]{});
    }
}

EDIT:

Этот метод расширения действительно работает с фабрикой, созданной Castle Windsor.

Вот мой оригинальный тестовый код, который вы можете вставить в Program.cs консольного приложения VS2010, добавить ссылку на 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
    {
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...