[英]use reflection to get type from an interface
Given the following types 鉴于以下类型
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; }
...
}
At configuration time I know all of the ValidationDefinitions; 在配置时,我知道所有的ValidationDefinitions。 "MyTestDummyClassValidationDef " above is an example of such a definition. 上面的“ MyTestDummyClassValidationDef”就是这样一个定义的例子。
If you follow the inheritance / implementation trail, at the end is an EntityType that is exposed by IClassMapping. 如果遵循继承/实现轨迹,则最后是IClassMapping公开的EntityType。
As part of my validation infrastructure, various objects may be asked to validate themselves. 作为我的验证基础结构的一部分,可能会要求各种对象进行自我验证。 The objects may or may not have a ValidationDef defined for them, either because validation doesn't apply fo that object or the definition hasn't been written yet. 这些对象可能有也可能没有为其定义ValidationDef,这是因为验证不适用于该对象,或者尚未写入定义。 If an object is asked to validate itself and there is no definition then a runtime error will occur. 如果要求对象进行自我验证且没有定义,则将发生运行时错误。
SO, what I am trying to is have a list of EntityTypes that I can use to check at runtime. 所以,我想要做的是有一个EntityTypes列表,我可以在运行时检查它。 If the object being asked to validate itself is not on the list then I can avoid the runtime error that would otherwise occur. 如果要求对象进行自我验证的对象不在列表中,则可以避免发生运行时错误。
How might I do that? 我该怎么办?
Cheers, 干杯,
Berryl 贝里
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);
}
If I understand this correctly, you want to call an explicit interface implementation of a method, ie a method that implements an interface method and that is only visible in the interface itself, not in the class. 如果我正确理解这一点,则需要调用方法的显式接口实现,即,一种实现接口方法的方法,该方法仅在接口本身中可见,而在类中不可见。
In order to do so, first retrieve the Type
object for IClassMapping
(with typeof(IClassMapping)
). 为此,请首先检索IClassMapping
的Type
对象(带有typeof(IClassMapping)
)。 On that object, call GetProperty
to retrieve a PropertyInfo
instance for the EntityType
property. 在该对象上,调用GetProperty
来检索EntityType
属性的PropertyInfo
实例。
You should then be able to retrieve the property value by invoking PropertyInfo.GetValue
on your ValidationDef<T>
instance. 然后,您应该能够通过在ValidationDef<T>
实例上调用PropertyInfo.GetValue
来检索属性值。
Use, for example, this method: 使用例如以下方法:
Type GetEntityType(ValidationDef<T> def)
{
PropertyInfo prop = typeof(IClassMapping).GetProperty("EntityType");
return (Type)prop.GetValue(def, null);
}
Ok, after clarification (see comments to the question), here is the way to find all implementations of ValidationDef in an assembly and create a list of values of their EntityType properties: 好的,在澄清之后(请参阅问题注释),这是在程序集中查找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;
}
Few points to note here: 这里要注意的几点:
Assembly.GetExecutingAssembly
). 正在检查当前程序集中的类型( Assembly.GetExecutingAssembly
)。 Obviously, this may or may not be sufficient for your scenario. 显然,这可能足以满足您的情况。 BaseType
returns the direct parent of the type being examined. BaseType
返回所检查类型的直接父级。 Again, you may want to examine the type hierarchy a bit further up the inheritance chain. 同样,您可能想在继承链的更深处检查类型层次结构。 Activator.CreateInstance
bit won't work. 否则, Activator.CreateInstance
位将不起作用。 Although it is certainly possible to do what you ask, I would like to strongly emphasize that it is very likely that there is much, much simpler solution to your validation needs. 尽管当然可以按照您的要求进行操作,但我想特别强调一下,很可能有很多非常简单的解决方案可以满足您的验证需求。 From what you've told us of your solution, it is obvious that it has a few serious flaws: 根据您对解决方案的了解,很明显它存在一些严重的缺陷:
Perhaps try to create a separate question detailing your validation needs. 也许尝试创建一个单独的问题,详细说明您的验证需求。 I am sure that a simpler solution can be found. 我相信可以找到一个更简单的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.