jeudi 5 février 2015

underlyingSystemType breaks class inheritance when using Reflection?

Sorry for the lengthy question. I want to give some context to what I need to do and the problem I am facing. My question is at the bottom if you feel you can answer it without the back story. Thanks in advance!


I am needing to use the Microsoft.Practices.EnterpriseLibrary to build an XML validation file. As part of Enterprise Library framework, you can create your own custom validators to expand on the basic validator types (ValueValidator, DateTimeValidator, DomainValidator, etc.). To do this, I must extend the Microsoft.Practices.EnterpriseLibrary.Validation.Validator abstract class so the EntLibConfig.exe, a configuration file editor that comes with the framework, can recognize which types are Validator types it can interact with. Below shows what I have done to implement this abstract class.


CustomValidation.dll:



namespace ValidationHOL.CustomValidators
{
[ConfigurationElementType(typeof (SSNValidator))]
public class MyValidator : Microsoft.Practices.EnterpriseLibrary.Validation.Validator
{
public MyValidator(string tag)
: this(tag, false)
{
}

public MyValidator(string tag, bool ignoreHypens)
: base(string.Empty, tag)
{
}

public MyValidator(NameValueCollection attributes)
: base(string.Empty, string.Empty)
{
}

public override void DoValidate(object objectToValidate,
object currentTarget,
string key,
ValidationResults validationResults)
{
throw new NotImplementedException();
}

protected override string DefaultMessageTemplate
{
get { throw new NotImplementedException(); }
}
}
}


When I try to load CustomValidation.dll in to the EntLibConfig.exe tool so I can use the MyValidator class in my configuration file nothing shows up!


So I opened up the source code for this EntLibConfig.exe and found where the application filters out classes it doesn't know how to use.


From Microsoft's Configuration.Console.csproj file (Part of the EnterpriseLibrary Framework):



namespace Microsoft.Practices.EnterpriseLibrary.Configuration.Design.ComponentModel.Editors
{
public class TypeBuildNodeConstraint
{

/* other code here*/

public bool Matches(Type type)
{
if (!this.BaseType.IsAssignableFrom(type))
//if (!this.BaseType.IsAssignableFrom(type))
{
var resolvedType = Type.GetType(type.AssemblyQualifiedName, false);
if (resolvedType == null // couldn't resolve it
|| resolvedType == type // resolve to the same type we had, which already failed to match
|| !this.BaseType.IsAssignableFrom(resolvedType)) // is a different, non-null type but doesn't match
return false;

type = resolvedType; // the new type matches, keep using it
}

if (!this.includeInterfaces && type.IsInterface)
return false;

if (!includeAbstractTypes && (type.IsAbstract && !type.IsInterface))
return false;

if (!this.includeBaseType && (type == this.BaseType))
return false;

if (!includeNonPublicTypes && !(type.IsPublic || type.IsNestedPublic))
return false;

if (this.ConfigurationType != null)
{
var attribute =
type.GetCustomAttributes(typeof(ConfigurationElementTypeAttribute), true)
.Cast<ConfigurationElementTypeAttribute>()
.FirstOrDefault();

if (attribute == null || this.ConfigurationType != attribute.ConfigurationType)
return false;
}

return true;
}
}
}


When I debug into this section of the code I get; The this.BaseType variable is of type Type and is showing information for the type Microsoft.Practices.EnterpriseLibrary.Validation.Validator and the type variable is of type Type and shows information for the type CustomValidator.MyValidator. My classMyValidator is getting returned as not a match when it fails the first if statement with the condition !this.BaseType.IsAssignableFrom(type). Turns out the type variable is showing the MyValidator class has a UnderlyingSystemType = CustomValidator.MyValidator instead of what I guess should be Microsoft.Practices.EnterpriseLibrary.Validation.Validator. type.BaseType shows Microsoft.Practices.EnterpriseLibrary.Validation.Validator which I take means that MyValidator inherits from Microsoft.Practices.EnterpriseLibrary.Validation.Validator.


So my question is: Why can I do this and it is valid:



Microsoft.Practices.EnterpriseLibrary.Validation.Validator tmpValidator =
new MyValidator;


But this returns false:



typeof(Microsoft.Practices.EnterpriseLibrary.Validation.Validator)
.IsAssignableFrom(typeof(MyValidator))


Is there something special I need to do to get this statement to return true: typeof(Microsoft.Practices.EnterpriseLibrary.Validation.Validator).IsAssignableFrom(typeof(MyValidator))? Can someone please help me understand why this is not acting the way I think it should?






Aucun commentaire:

Enregistrer un commentaire