-
Notifications
You must be signed in to change notification settings - Fork 57
/
Copy pathFilterAttribute.cs
83 lines (67 loc) · 2.72 KB
/
FilterAttribute.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
using PostSharp.Aspects;
using PostSharp.Extensibility;
using PostSharp.Reflection;
using PostSharp.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace PostSharp.Samples.Encryption
{
[PSerializable]
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property)]
public abstract class FilterAttribute : Attribute, IAspectProvider
{
public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
{
var parameter = targetElement as ParameterInfo;
if (parameter != null)
{
// When the attribute is applied on a parameter, we have to apply the filter when the method is invoked.
var method = (MethodBase) parameter.Member;
// Add an aspect to the method. Make sure we have a single aspect instance even if many parameters need filtering.
var filterMethodArgumentsAspect = GetAspect<FilterMethodArgumentsAspect>(method);
if (filterMethodArgumentsAspect == null)
{
filterMethodArgumentsAspect = new FilterMethodArgumentsAspect(method);
yield return new AspectInstance(method, filterMethodArgumentsAspect);
}
filterMethodArgumentsAspect.SetFilter(parameter, this);
}
else
{
// When the attribute is applied on a field or property, we will apply the filter when asked implicitly.
var locationInfo = LocationInfo.ToLocationInfo(targetElement);
if (locationInfo.IsStatic)
{
Message.Write(locationInfo, SeverityType.Error, "MY02", "Cannot apply [{0}] to {1} because it is static.",
GetType().Name, locationInfo);
yield break;
}
var type = locationInfo.DeclaringType;
if (type.IsValueType)
{
Message.Write(locationInfo, SeverityType.Error, "MY03",
"Cannot apply [{0}] to {1} because the declaring type is a struct.", GetType().Name, locationInfo);
yield break;
}
var filterTypePropertiesAspect = GetAspect<FilterTypePropertiesAspect>(type);
if (filterTypePropertiesAspect == null)
{
filterTypePropertiesAspect = new FilterTypePropertiesAspect();
yield return new AspectInstance(type, filterTypePropertiesAspect);
}
filterTypePropertiesAspect.SetFilter(locationInfo, this);
}
}
public abstract object ApplyFilter(object value);
private static T GetAspect<T>(object target)
{
return PostSharpEnvironment.CurrentProject.GetService<IAspectRepositoryService>()
.GetAspectInstances(target)
.Select(aspectInstance => aspectInstance.Aspect)
.OfType<T>()
.SingleOrDefault();
}
}
}