Ich habe ein Web-API-Projekt, in dem ich versuche, einen Abfrage-Handler zur Laufzeit mit dem Abfragetyp und dem Abfrage-Ergebnistyp aufzulösen. Unten ist ein Testcode, den ich als Beweis für das Konzept verwende. Ich benutze die Ninject Factory-Erweiterung, aber ich habe Probleme, die richtige Einstellung zu bekommen, da ich eine generische Schnittstelle zurückgeben möchte, vielleicht ist dies das falsche Design, so dass alle Vorschläge dankbar wären.Fehler beim Lösen der Abhängigkeit mit Ninject Factory-Erweiterungen
-Code
public interface IQueryHandlerFactory
{
IQueryHandler<IQuery, IQueryResult> Resolve(Type type);
}
public interface IQuery
{
}
public interface IQueryResult
{
}
public interface IQueryHandler<TQuery, TResult>
where TQuery : IQuery
where TResult : IQueryResult
{
TResult Execute(TQuery query);
}
public class PaymentQueryHandler : IQueryHandler<GetPayments, PaymentResult>
{
public PaymentResult Execute(GetPayments query)
{
throw new NotImplementedException();
}
}
public class UserQueryHandler : IQueryHandler<GetUsers, UserResult>
{
public UserResult Execute(GetUsers query)
{
throw new NotImplementedException();
}
}
public class TypeInstanceProvider : StandardInstanceProvider
{
protected override Type GetType(MethodInfo methodInfo, object[] arguments)
{
var type = arguments[0] as Type;
return type;
}
protected override IConstructorArgument[] GetConstructorArguments(MethodInfo methodInfo, object[] arguments)
{
return base.GetConstructorArguments(methodInfo, arguments).Skip(1).ToArray();
}
public override object GetInstance(IInstanceResolver instanceResolver, MethodInfo methodInfo, object[] arguments)
{
Type t = this.GetType(methodInfo, arguments);
var test = instanceResolver.Get(t,
null,
null,
this.GetConstructorArguments(methodInfo, arguments),
false);
return test;
}
}
Ich bin gerade mit einigen Ninject Prüfung ruft in meinem NinjectWebCommon für jetzt, um zu sehen, ob es funktionieren würde. Ich möchte in der Lage sein, die MakeGenericType
Methode zu verwenden, da ich den Abfragetyp und den Ergebnistyp kenne. Es funktioniert, wenn ich var test = kernel.Get(queryHandlerType);
jedoch nennen versagt es, wenn ich versuche unter
NinjectWebCommon Code, um die Fabrik zu verwenden:
kernel.Bind<IQueryHandlerFactory>().ToFactory(() => new TypeInstanceProvider());
var queryHandlerType = typeof(IQueryHandler<,>).MakeGenericType(typeof(GetPayments), typeof(PaymentResult));
var factory = kernel.Get<IQueryHandlerFactory>();
var test = kernel.Get(queryHandlerType); // This works
var handler = factory.Resolve(queryHandlerType); // This fails
Der Fehler, der erzeugt wird, ist unter
Exception thrown: 'System.InvalidCastException' in DynamicProxyGenAssembly2
Additional information: Unable to cast object of type 'PaymentQueryHandler' to type 'IQueryHandler`2[IQuery,IQueryResult]'.
kann ich gut über sein Dinge komplizieren, oder ist das überhaupt möglich? Ich würde es haben. Hat jemand irgendwelche Vorschläge, um das zu funktionieren?
Ihre Lösung wies mich in die richtige Richtung, danke – Gavin