Какой контроль у меня над инструментами TypedFactory Windsor?
Мой коллега настроил 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 ответ
Вы хотите назвать что-то вроде 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.
Вот мой оригинальный тестовый код, который вы можете вставить в 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 Stackru9198461
{
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
{
}
}