簡體   English   中英

C#如何重構代碼以使用接口反射

[英]C# How can I refactor code to use interface reflection

我有一個列表,我一直在其中添加繼承IValidation接口的驗證類,但是現在我想使用反射來顯式遍歷所有繼承ISpecialCaseRequestValidation接口的類。

這是我的驗證類:

private static List<IValidation> _validations = new List<IValidation>();

static Validations()
{
}

public static bool IsValid(SpecialCaseRequest specialCase, out HttpResponseMessage response)
{
    var result = _validations.FirstOrDefault(v => !v.IsValid(SpecialCase, out error));
    if (result != null)
    {
        return false;
    }
    return true;
}

現在我對!v.IsValid ,因為我已經將IsValidIValidation移到了ISpecialCaseRequestValidation接口。 這是我的界面:

public interface ISpecialCaseRequestValidation: IValidation
{
    bool IsValid(SpecialCaseRequest specialCase, out Error error);
}
public interface IValidation
{
}

這是我的繼承ISpecialCaseRequestValidation接口的類:

public class NameValidation : ISpecialCaseRequestValidation
{
    public bool IsValid(SpecialCaseRequest specialCase, out Error error)
    {
        if (condition)
        {
            return false;
        } 
        return true;
    }
}

public class ExpirationDateTimeValidation : ISpecialCaseRequestValidation{}

public class AgeValidation : ISpecialCaseRequestValidation{}

如何通過反射定義這些接口,它將遍歷所有繼承ISpecialCaseRequestValidation接口和lambda表達式的類以選擇IsValid方法?

更新:

好吧,我有所有的類程序集,我看到它們的名稱:

Assembly a = typeof(ISpecialCaseRequestValidation).Assembly;
var list = a.GetTypes().Where(type => type != typeof(ISpecialCaseRequestValidation) && typeof(ISpecialCaseRequestValidation).IsAssignableFrom(type)).ToList();

但是問題是,當我使用var list我無法訪問類IsValid方法,只能看到類屬性。

我是這樣解決的:

static Validations()
{
Assembly a = typeof(ISpecialCaseRequestValidation).Assembly;
            _validationTypes =
                a.GetTypes()
                    .Where(
                        type =>
                            type != typeof(ISpecialCaseRequestValidation) &&
                            typeof(ISpecialCaseRequestValidation).IsAssignableFrom(type))
                    .ToList();
}

在這里,我得到Assembly of Interface類並將其放到列表中。

public static bool IsValid(SpecialCaseRequest specialCase, out HttpResponseMessage response)
{
    object[] mParam = new object[] { signingCase, new Error() };
        foreach (Type type in _validationTypes)
        {
            var obj = Activator.CreateInstance(type);
            var isValidMethod = type.GetMethod("IsValid");
            var isValid = (bool) isValidMethod.Invoke(obj, mParam);
        }
    if (result != null)
    {
        return false;
    }
    return true;
}

並使用object []遍歷在isValid變量中調用的所有IsValid()方法。

據我所知,您的接口聲明應更改為:

public interface ISpecialCaseRequestValidation: IValidation
{
}
public interface IValidation
{
    bool IsValid(SpecialCaseRequest specialCase, out Error error);
}

它繼承所有類ISpecialCaseRequestValidation將必須實現IsValid ,因此將所有的類,其繼承IValidation 我建議這樣做是因為我認為也應該檢查來自IValidation孩子的有效性。

我想補充一點,你可以寫

public static bool IsValid(SpecialCaseRequest specialCase, out HttpResponseMessage response) =>
    _validations.All(v => v.IsValid(specialCase, out error));

代替

public static bool IsValid(SpecialCaseRequest specialCase, out HttpResponseMessage response)
{
    var result = _validations.FirstOrDefault(v => !v.IsValid(SpecialCase, out error));
    if (result != null)
    {
        return false;
    }
    return true;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM