私はcastle windsorのサブ依存関係リゾルバを作成しています。リゾルバは汎用インタフェースを実装するオブジェクトを返します。汎用パラメータは実行時に解決され、ファクトリは正しい実装を返すために使用されます。ファクトリメソッドの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の一般的なパラメータをMethodCallExpressionから変更する方法や、MethodInfoからそれを 'Parent'に戻し、必要な型を使用してMakeGenericMethodを呼び出す方法があることを期待していました。
Reflection APIを使用しているオープンジェネリックをサポートしています。それは悲しい事実です。それがうまくいくなら、それをそのまま残して、もっと面白い仕事に移りなさい。私はこれにあまりにも多くの時間を費やすことはありません。 –
@ KrzysztofあなたがOCDでないなら、それはいいです:)。ウェイクアップコールに感謝します。 – Bronumski