Reputation: 12833
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; "MyTestDummyClassValidationDef " above is an example of such a definition.
If you follow the inheritance / implementation trail, at the end is an EntityType that is exposed by IClassMapping.
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. 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. 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);
}
Upvotes: 0
Views: 3262
Reputation: 7088
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:
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
). Obviously, this may or may not be sufficient for your scenario.BaseType
returns the direct parent of the type being examined. Again, you may want to examine the type hierarchy a bit further up the inheritance chain.Activator.CreateInstance
bit won't work. 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.
Upvotes: 0
Reputation: 20722
If I understand this correctly, you want to call an explicit interface implementation of a method, i.e. 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)
). On that object, call GetProperty
to retrieve a PropertyInfo
instance for the EntityType
property.
You should then be able to retrieve the property value by invoking PropertyInfo.GetValue
on your ValidationDef<T>
instance.
Use, for example, this method:
Type GetEntityType(ValidationDef<T> def)
{
PropertyInfo prop = typeof(IClassMapping).GetProperty("EntityType");
return (Type)prop.GetValue(def, null);
}
Upvotes: 1