C#如何重构代码以使用接口反射

时间:2017-02-06 09:43:23

标签: c# inheritance reflection lambda interface

我有一个列表,我一直在添加继承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方法,我只能看到类属性。

2 个答案:

答案 0 :(得分:0)

我用这种方式解决了它:

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()方法。

答案 1 :(得分:-1)

据我所知,您的界面声明应更改为:

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