2017-05-23 15 views
1

は、次の拡張方法を検討して、一般的な拡張メソッドを呼び出す:パラメータ

public static class ValiDoc 
{ 
     public static IEnumerable<RuleDescription> GetRules<T>(this AbstractValidator<T> validator, bool documentNested = false) 
     { 
      //.... 
     } 
} 

AbstractValidatorの実装:

public class AddressValidator : AbstractValidator<Address> 
{ 
    public AddressValidator() 
    { 
     RuleFor(address => address.HouseNumber).NotEmpty(); 
     RuleFor(address => address.StreetName).NotEmpty(); 
     RuleFor(address => address.PostCode).NotEmpty(); 
    } 
} 

を私は反射とパスを経由してValiDoc上GetRules()拡張メソッドを呼び出したいです最初のパラメータとしてAddressValidatorのインスタンスで、2番目のパラメータに対してブール値を使用します。

私はかなり圧倒される前にReflectionで遊んだことはないが、ここで利用可能な例に従うことによって、私はの一部をとした。

//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); 

generatedGetRules.Invokeを実行する場合、私は、次のエラーメッセージが表示されますValiDoc.Tests.TestData.Validators.AddressValidator ' 型に変換することができない 'FluentValidation

' 型のオブジェクトを' .AbstractValidator 1[FluentValidation.AbstractValidator 1 [ValiDoc.Tests.TestData.POCOs.Address]] '。'

わかりません。私が近くにいるのか、何マイル離れているのかは分かりません。

サポート値:

typeof演算(AbstractValidator <>)= {FluentValidation.AbstractValidator`1 [T]}

childValidator.ValidatorType.GetTypeInfo()BaseType.GenericTypeArguments [0] = { ValiDoc.Tests.TestData.POCOs.Address}

構築

= {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]、ブール値)}

パラメーター配列= {ValiDoc.Tests.TestData.Validators .AddressValidator}、ブール

EDIT: 作業を実装:あなたのエラーメッセージに

// 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>; 

答えて

1

、私が見るAddressValidatorAbstractValidator<Address>)をAbstractValidator<AbstractValidator<Address>>に変換することはできません。構築されたではなく、 MakeGenericMethodに渡したいものがあります。メソッドはTで汎用的ですが、最初の引数はthis AbstractValidator<T>なので、必要なものの代わりに2つの汎用特殊化が得られます。

+0

答えが返ってきました。 多くのご協力ありがとうございます:) –