Aufrufen Sie sich das folgende Erweiterungsmethode:generische Erweiterungsmethode mit Parametern
public static class ValiDoc
{
public static IEnumerable<RuleDescription> GetRules<T>(this AbstractValidator<T> validator, bool documentNested = false)
{
//....
}
}
Eine Implementierung von AbstractValidator:
public class AddressValidator : AbstractValidator<Address>
{
public AddressValidator()
{
RuleFor(address => address.HouseNumber).NotEmpty();
RuleFor(address => address.StreetName).NotEmpty();
RuleFor(address => address.PostCode).NotEmpty();
}
}
Ich möchte die getRules() Erweiterungsmethode auf ValiDoc über Reflexion und Pass aufzurufen in einer Instanz von AddressValidator als der erste Parameter mit einem booleschen Wert für die Sekunde.
Ich habe noch nie zuvor mit Reflection gespielt, aber ich bin ziemlich überwältigt, aber wenn ich die hier verfügbaren Beispiele befolge, habe ich einige Fortschritte gemacht.
//Parameter 1
Type type = typeof(AbstractValidator<>);
// Instance of Address
Type constructed = type.MakeGenericType(childValidator.ValidatorType.GetTypeInfo().BaseType.GenericTypeArguments[0]);
// Find the extension method based on the signature I have defined for the usage
// public static IEnumerable<RuleDescription> GetRules<T>(this AbstractValidator<T> validator, bool documentNested = false)
var runtimeMethods = typeof(ValiDoc).GetRuntimeMethods();
MethodInfo generatedGetRules = null;
// Nothing fancy for now, just pick the first option as we know it is GetRules
using (IEnumerator<MethodInfo> enumer = runtimeMethods.GetEnumerator())
{
if (enumer.MoveNext()) generatedGetRules = enumer.Current;
}
// Create the generic method instance of GetRules()
generatedGetRules = generatedGetRules.MakeGenericMethod(constructed);
//Parameter 1 = Derived from AbstractValidator<T>, Parameter 2 = boolean
var parameterArray = new object[] { childValidator.GetValidator(new PropertyValidatorContext(new ValidationContext(rule.Member.DeclaringType), rule, propertyName)), true };
//Invoke extension method with validator instance
generatedGetRules.Invoke(null, parameterArray);
Wenn generatedGetRules.Invoke Ausführung erhalten I wird folgende Fehlermeldung:
'Objekt des Typs '' nicht konvertiert werden kann eingeben' ValiDoc.Tests.TestData.Validators.AddressValidator FluentValidation .AbstractValidator
1[FluentValidation.AbstractValidator
1 [ValiDoc.Tests.TestData.POCOs.Address]] '.'
Habe ich etwas offensichtlich übersehen? Ich kann nicht sagen, ob ich fast da bin oder Meilen entfernt bin.
Stützwerte.
typeof (AbstractValidator <>) = {FluentValidation.AbstractValidator`1 [T]}
childValidator.ValidatorType.GetTypeInfo() BaseType.GenericTypeArguments [0] = { ValiDoc.Tests.TestData.POCOs.Address}
konstruiert = {FluentValidation.AbstractValidator`1 [ValiDoc.Tests.TestData.POCOs.Address]}
gener atedGetRules = {System.Collections.Generic.IEnumerable 1[ValiDoc.Output.RuleDescription] GetRules[AbstractValidator
1] (FluentValidation.AbstractValidator 1[FluentValidation.AbstractValidator
1 [ValiDoc.Tests.TestData.POCOs.Address]], Boolean)}
Parameter array = {ValiDoc.Tests.TestData.Validators .AddressValidator}, boolean
EDIT: Arbeits Umsetzung:
// Find the extension method based on the signature I have defined for the usage
// public static IEnumerable<RuleDescription> GetRules<T>(this AbstractValidator<T> validator, bool documentNested = false)
var runtimeMethods = typeof(ValiDoc).GetRuntimeMethods();
MethodInfo generatedGetRules = null;
// Nothing fancy for now, just pick the first option as we know it is GetRules
using (IEnumerator<MethodInfo> enumer = runtimeMethods.GetEnumerator())
{
if (enumer.MoveNext()) generatedGetRules = enumer.Current;
}
// Create the generic method instance of GetRules()
generatedGetRules = generatedGetRules.MakeGenericMethod(childValidator.ValidatorType.GetTypeInfo().BaseType.GenericTypeArguments[0]);
//Parameter 1 = Derived from AbstractValidator<T>, Parameter 2 = boolean
var parameterArray = new object[] { childValidator.GetValidator(new PropertyValidatorContext(new ValidationContext(rule.Member.DeclaringType), rule, propertyName)), true };
//Invoke extension method with validator instance
var output = generatedGetRules.Invoke(null, parameterArray) as IEnumerable<RuleDescription>;
Nailed it - Frage mit Antwort aktualisiert. Vielen Dank für Ihre Hilfe :) –