성 윈저에 대한 하위 종속성 해결 프로그램을 작성 중입니다. 해석기는 일반 인터페이스를 구현하는 객체를 반환합니다. 제네릭 매개 변수는 런타임에 확인되고 팩토리는 올바른 구현을 반환하는 데 사용됩니다. 나는 factory 메소드의 MethodInfo를 얻기 위해 문자열을 사용하고 싶지 않다. 다음은 작동하지만 공장 생성 메서드를 해결하는 더 좋은 방법이 있어야한다고 생각합니다. GetMethodName 및이 메서드 사용 방법을 참조하십시오.리플렉션을 사용하여 문자열 이름을 사용하지 않고 일반 MethodInfo를 가져오고 런타임시 일반 매개 변수가 해석됩니다.
public class FooFactoryResolver : ISubDependencyResolver
{
private static string factoryMethodName;
private readonly IWindsorContainer container;
public FooFactoryResolver (IWindsorContainer container)
{
this.container = container;
}
private static string GetMethodName()
{
if (factoryMethodName == null)
{
IFooFactory fooFactory = null;
Expression<Func<IFoo<object, object>>> expression =
() => fooFactory .CreateFoo<object, object>();
factoryMethodName = ((MethodCallExpression)expression.Body).
Method.Name;
}
return factoryMethodName;
}
public object Resolve(CreationContext context,
ISubDependencyResolver contextHandlerResolver,
Castle.Core.ComponentModel model, DependencyModel dependency)
{
return
TryToResolveDirectly(dependency) ??
TryToResolveUsingFactories(dependency) ??
ComponentNotFound(dependency);
}
private static object ComponentNotFound(DependencyModel dependency)
{
throw new ComponentNotFoundException(dependency.TargetType);
}
private object TryToResolveUsingFactories(DependencyModel dependency)
{
var fooFactories = this.container.ResolveAll<IFooFactory>();
Type[] genericTypes = dependency.TargetItemType.
GetGenericArguments().ToArray();
return (from fooFactory in fooFactories
where fooFactory.CanCreate(genericTypes[0],
genericTypes[1])
let factoryMethod = fooFactory.GetType().
GetMethod(GetMethodName())
select factoryMethod.MakeGenericMethod(
genericTypes.ToArray()).
Invoke(fooFactory, new object[0])).
FirstOrDefault();
}
private object TryToResolveDirectly(DependencyModel dependency)
{
return this.container.Kernel.HasComponent(dependency.TargetType) ?
this.container.Resolve(dependency.TargetType) : null;
}
public bool CanResolve(CreationContext context,
ISubDependencyResolver contextHandlerResolver,
Castle.Core.ComponentModel model, DependencyModel dependency)
{
return dependency.TargetType.GetGenericTypeDefinition() ==
typeof(IFoo<,>);
}
}
public interface IFoo<T1, T2> { }
public interface IFooFactory
{
IFoo<T1, T2> CreateFoo<T1, T2>();
bool CanCreate(Type a, Type b);
}
이것이 학대인지 아닌지는 잘 모르겠지만 일을 끝내면 나는 분명히 뭔가 빠져 있다고 느낍니다. MethodInfo의 generic 매개 변수를 MethodCallExpression에서 변경하거나 MethodInfo에서 'Parent'로 돌아가서 원하는 유형을 사용하여 MakeGenericMethod를 호출하는 방법이있을 것으로 기대하고 있습니다.
Reflection API에서 공개 제네릭을 지원합니다. 슬픈 사실입니다. 작동하는 경우 - 그냥 그대로두고 더 재미있는 작업으로 이동하십시오. 나는 이것에 너무 많은 시간을 쓰지 않을 것이다. –
@Krzysztof OCD가 아니라면 괜찮습니다. :). 웨이크 업 전화에 감사드립니다. – Bronumski