0

给定以下类型

private class MyTestDummyClassValidationDef : ValidationDef<MyTestDummyClass>
    {
        ...
    }

public class ValidationDef<T> : IValidationDefinition<T>, IConstraintAggregator, IMappingSource where T : class        
{        }

public interface IMappingSource
{
    IClassMapping GetMapping();
}

public interface IClassMapping
{
    Type EntityType { get; }
    ...
}

在配置时,我知道所有的 ValidationDefinitions;上面的“MyTestDummyClassValidationDef”就是这种定义的一个例子。

如果您遵循继承/实现线索,最后是由 IClassMapping 公开的 EntityType。

作为我的验证基础设施的一部分,可能会要求各种对象进行自我验证。对象可能有也可能没有为它们定义的 ValidationDef,因为验证不适用于该对象或尚未编写定义。如果一个对象被要求验证自己并且没有定义,那么将发生运行时错误。

所以,我想要的是有一个 EntityTypes 列表,我可以用来在运行时检查。如果要求验证自身的对象不在列表中,那么我可以避免否则会发生的运行时错误。

我该怎么做?

干杯,
贝里尔

我正在寻找的代码

public EntityValidator(ValidatorEngine validatorEngine, IEnumerable<Type> defTypes) {

ValidationDefs = new List<Type>();
foreach (var type in defTypes) 
{
    if (type.BaseType.GetGenericTypeDefinition() != typeof(ValidationDef<>)) continue;

    var mappingSource = (IMappingSource) Activator.CreateInstance(type);
    var entityType = mappingSource.GetMapping().EntityType;
    ValidationDefs.Add(entityType);
}
4

2 回答 2

1

如果我理解正确,您想调用方法的显式接口实现,即实现接口方法并且仅在接口本身中可见的方法,而不是在类中。

为此,首先检索(with )的Type对象。在该对象上,调用以检索该属性的实例。IClassMappingtypeof(IClassMapping)GetPropertyPropertyInfoEntityType

然后,您应该能够通过调用PropertyInfo.GetValue您的ValidationDef<T>实例来检索属性值。

例如,使用此方法:

Type GetEntityType(ValidationDef<T> def)
{
    PropertyInfo prop = typeof(IClassMapping).GetProperty("EntityType");
    return (Type)prop.GetValue(def, null);
}
于 2012-06-22T19:08:30.913 回答
0

好的,在澄清之后(请参阅问题的评论),这是在程序集中查找 ValidationDef 的所有实现并创建其 EntityType 属性的值列表的方法:

List<Type> entityTypes = new List<Type>();

foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
    if (InheritsFromValidationDef(type))
    {
        IMappingSource mappingSource = (IMappingSource)Activator.CreateInstance(type);
        entityTypes.Add(mappingSource.GetMapping().EntityType);
    }
}

private static bool InheritsFromValidationDef(Type type)
{
    Type baseType = type.BaseType;
    bool result = baseType != null && 
                  baseType.IsGenericType &&
                  baseType.GetGenericTypeDefinition() == typeof(ValidationDef<>);
    return result;
}

这里有几点需要注意:

  • 正在检查当前程序集中的类型 ( Assembly.GetExecutingAssembly)。显然,这对于您的场景可能或可能不够。
  • BaseType返回正在检查的类型的直接父级。同样,您可能希望在继承链的更上方检查类型层次结构。
  • 假设所有检查的类型都有一个无参数的构造函数。否则,Activator.CreateInstance位将不起作用。

尽管可以按照您的要求进行操作,但我想强烈强调,您的验证需求很可能有很多、更简单的解决方案。从您告诉我们的解决方案来看,很明显它有一些严重的缺陷:

  • 您怎么可能对无法验证的对象调用验证?我想这是你所有悲伤的根源。
  • 您的继承层次结构过于复杂且难以理解。为什么需要这么多接口?

也许尝试创建一个单独的问题来详细说明您的验证需求。我确信可以找到更简单的解决方案。

于 2012-06-22T20:20:53.583 回答