How do xaml built-in extensions access IXamlTypeResolver when custom cannot work in Dev Studio 2010?

I wrote a custom xaml extenstion, but it could not get IXamlTypeResolver during development. I made some points, and it seems to be related to the error introduced in dev studio 2010. As an experiment, I decompiled x: Static and rebuilt as an external extension, but also cannot get the IXamlTypeResolver file. However, the assembly works during development. There must be some kind of inner magic. I am wondering if there are any workarounds. I don’t mind doing the extra work to get the information I need, for example, to analyze the namespace xaml declarations, but it seems that the services I need for this are also not available during development. Does Microsoft have any plans to fix this problem? This severely limits the usefulness of custom xaml extensions.This should affect third-party library providers - I wonder how they work.

[MarkupExtensionReturnType(typeof(object))]
[TypeConverter(typeof(MyStaticExtensionConverter))]
public class MyStaticExtension : MarkupExtension
{
    private string _member;
    private Type _memberType;

    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    [EditorBrowsable(EditorBrowsableState.Advanced)]
    public MyStaticExtension()
    {
    }

    public MyStaticExtension(string member)
    {
        if (member == null) {
            throw new ArgumentNullException("member");
        }
        this._member = member;
    }

    private bool GetFieldOrPropertyValue(Type type, string name, out object value)
    {
        FieldInfo field = null;
        Type baseType = type;
        do {
            field = baseType.GetField(name, BindingFlags.Public | BindingFlags.Static);
            if (field != null) {
                value = field.GetValue(null);
                return true;
            }
            baseType = baseType.BaseType;
        }
        while (baseType != null);
        PropertyInfo property = null;
        baseType = type;
        do {
            property = baseType.GetProperty(name, BindingFlags.Public | BindingFlags.Static);
            if (property != null) {
                value = property.GetValue(null, null);
                return true;
            }
            baseType = baseType.BaseType;
        }
        while (baseType != null);
        value = null;
        return false;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (this._member == null) {
            throw new InvalidOperationException("MarkupExtensionStaticMember");
        }

        Type memberType = this.MemberType;
        string str = null;
        string str2 = null;
        object obj2;
        if (memberType != null) {
            str = this._member;
            str2 = memberType.FullName + "." + this._member;
        }
        else {
            str2 = this._member;
            int index = this._member.IndexOf('.');
            if (index < 0) {
                throw new ArgumentException("MarkupExtensionBadStatic", this._member);
            }

            string qualifiedTypeName = this._member.Substring(0, index);
            if (qualifiedTypeName == string.Empty) {
                throw new ArgumentException("MarkupExtensionBadStatic", this._member);
            }

            if (serviceProvider == null) {
                throw new ArgumentNullException("serviceProvider");
            }

            IXamlTypeResolver service = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver;

            // Exception will thrown here as at design time
            if (service == null) {


                throw new ArgumentException("MarkupExtensionNoContext", base.GetType().Name);
            }

            memberType = service.Resolve(qualifiedTypeName);
            str = this._member.Substring(index + 1, (this._member.Length - index) - 1);
            if (str == string.Empty) {
                throw new ArgumentException("MarkupExtensionBadStatic", this._member);
            }
        }

        if (memberType.IsEnum) {
            return Enum.Parse(memberType, str);
        }

        if (!this.GetFieldOrPropertyValue(memberType, str, out obj2)) {
            throw new ArgumentException("MarkupExtensionBadStatic", str2);
        }

        return obj2;
    }

    [ConstructorArgument("member")]
    public string Member
    {
        [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
        get
        {
            return this._member;
        }
        set
        {
            if (value == null) {
                throw new ArgumentNullException("value");
            }
            this._member = value;
        }
    }

    [DefaultValue((string)null)]
    public Type MemberType
    {
        [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
        get
        {
            return this._memberType;
        }
        set
        {
            if (value == null) {
                throw new ArgumentNullException("value");
            }
            this._memberType = value;
        }
    }
}

internal class MyStaticExtensionConverter : TypeConverter
{
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return ((destinationType == typeof(InstanceDescriptor)) || base.CanConvertTo(context, destinationType));
    }

    [SecurityCritical, SecurityTreatAsSafe]
    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType != typeof(InstanceDescriptor)) {
            return base.ConvertTo(context, culture, value, destinationType);
        }

        MyStaticExtension extension = value as MyStaticExtension;
        if (extension == null) {
            throw new ArgumentException("MustBeOfType", "value");
        }

        return new InstanceDescriptor(typeof(MyStaticExtension).GetConstructor(new Type[] { typeof(string) }), new object[] { extension.Member });
    }
}
+3

All Articles