-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAttributeTypeDescriptor.cs
86 lines (77 loc) · 3.07 KB
/
AttributeTypeDescriptor.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NHail.ComponentModel.DataAnnotations.Fluent
{
public class AttributeTypeDescriptor : CustomTypeDescriptor
{
private readonly HashSet<Attribute> _attributes;
private readonly ILookup<string, Attribute> _propertyAttributes;
private readonly PropertyDescriptorCollection _propertyDescriptorCollection;
public AttributeTypeDescriptor(IEnumerable<Attribute> attributes,
IEnumerable<KeyValuePair<string, Attribute>> propertyAttributes,
ICustomTypeDescriptor parent) : base(parent)
{
_attributes = new HashSet<Attribute>(attributes);
_propertyAttributes =
propertyAttributes.ToLookup(kv => kv.Key, kv => kv.Value);
if (_propertyAttributes.Any())
{
_propertyDescriptorCollection =
new PropertyDescriptorCollection(CreateProperties(parent.GetProperties()).ToArray());
}
}
public override PropertyDescriptorCollection GetProperties()
{
return _propertyDescriptorCollection ?? base.GetProperties();
}
public override PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
return _propertyDescriptorCollection ?? base.GetProperties(attributes);
}
private IEnumerable<PropertyDescriptor> CreateProperties(PropertyDescriptorCollection properties)
{
foreach (PropertyDescriptor property in properties)
{
if (!_propertyAttributes.Contains(property.Name))
{
yield return property;
}
else
{
yield return TypeDescriptor.CreateProperty(property.ComponentType, property,
property.Attributes.Cast<Attribute>().Concat(_propertyAttributes[property.Name]).ToArray());
}
}
}
public override object GetPropertyOwner(PropertyDescriptor pd)
{
var owner = base.GetPropertyOwner(pd);
if (owner != null)
{
return owner;
}
if (_propertyAttributes.Contains(pd.Name))
{
return this;
}
return null;
}
public override AttributeCollection GetAttributes()
{
// Filter out any attributes that have the same TypeId
// using a hashset with an IEqualityComparer to do the work
// Add our attributes first then add any unique ones from the base code
var attributes = new HashSet<Attribute>(_attributes,
ProjectionEqualityComparer<Attribute>.Create(a => a.TypeId));
foreach (Attribute attribute in base.GetAttributes())
{
attributes.Add(attribute);
}
return new AttributeCollection(attributes.ToArray());
}
}
}