2 // Copyright (c) Microsoft Corporation. All rights reserved.
5 namespace Microsoft.Activities.Presentation.Xaml
8 using System.Collections;
9 using System.ComponentModel;
10 using System.ComponentModel.Design.Serialization;
11 using System.Globalization;
12 using System.Reflection;
14 // AttributeConverter is to convert some XAML-unfriendly attributes (without default ctor) to InstanceDescriptor for XAML serialization
15 internal class AttributeConverter<TAttribute, TAttributeInfo> : TypeConverter
16 where TAttribute : Attribute
17 where TAttributeInfo : AttributeInfo<TAttribute>, new()
19 private static ConstructorInfo attributeConstructor = null;
20 private TAttributeInfo attributeInfo = new TAttributeInfo();
22 private ConstructorInfo Constructor
26 // no need to lock here because every thread will generate the same constructor info even in race condition
27 // and cost to get the constructor is relative small
28 if (AttributeConverter<TAttribute, TAttributeInfo>.attributeConstructor == null)
30 AttributeConverter<TAttribute, TAttributeInfo>.attributeConstructor = this.attributeInfo.GetConstructor();
33 return AttributeConverter<TAttribute, TAttributeInfo>.attributeConstructor;
37 public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
39 if (destinationType == typeof(InstanceDescriptor))
44 return base.CanConvertTo(context, destinationType);
47 public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
52 public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
54 if (destinationType != typeof(InstanceDescriptor))
56 return base.ConvertTo(context, culture, value, destinationType);
59 TAttribute attribute = value as TAttribute;
61 SharedFx.Assert(value != null, "The usage should be guaranteed by the XAML stack");
63 ConstructorInfo constructor = this.Constructor;
64 ICollection arguments = this.attributeInfo.GetConstructorArguments(attribute, ref constructor);
65 return new InstanceDescriptor(constructor, arguments, this.attributeInfo.IsComplete);