Merge pull request #2250 from esdrubal/master
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / Microsoft.Tools.Common / Microsoft / Activities / Presentation / Xaml / AttributeConverter.cs
1 // <copyright>
2 //   Copyright (c) Microsoft Corporation.  All rights reserved.
3 // </copyright>
4
5 namespace Microsoft.Activities.Presentation.Xaml
6 {
7     using System;
8     using System.Collections;
9     using System.ComponentModel;
10     using System.ComponentModel.Design.Serialization;
11     using System.Globalization;
12     using System.Reflection;
13
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()
18     {
19         private static ConstructorInfo attributeConstructor = null;
20         private TAttributeInfo attributeInfo = new TAttributeInfo();
21
22         private ConstructorInfo Constructor
23         {
24             get
25             {
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)
29                 {
30                     AttributeConverter<TAttribute, TAttributeInfo>.attributeConstructor = this.attributeInfo.GetConstructor();
31                 }
32
33                 return AttributeConverter<TAttribute, TAttributeInfo>.attributeConstructor;
34             }
35         }
36
37         public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
38         {
39             if (destinationType == typeof(InstanceDescriptor))
40             {
41                 return true;
42             }
43
44             return base.CanConvertTo(context, destinationType);
45         }
46
47         public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
48         {
49             return false;
50         }
51
52         public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
53         {
54             if (destinationType != typeof(InstanceDescriptor))
55             {
56                 return base.ConvertTo(context, culture, value, destinationType);
57             }
58
59             TAttribute attribute = value as TAttribute;
60
61             SharedFx.Assert(value != null, "The usage should be guaranteed by the XAML stack");
62
63             ConstructorInfo constructor = this.Constructor;
64             ICollection arguments = this.attributeInfo.GetConstructorArguments(attribute, ref constructor);
65             return new InstanceDescriptor(constructor, arguments, this.attributeInfo.IsComplete);
66         }
67     }
68 }