. 애스펙트 타겟의 고급 필터링의 경우 애스펙트에서 CompileTimeValidate 메소드를 오버라이드하고 프로그래밍 방식으로 필터링 할 수 있습니다.
그러나 설명 된 경우에도이 정도면 충분하지 않습니다. 메서드에 애스펙트를 MyClass<T>
에 적용했다고 가정 해 보겠습니다. 컴파일 시점에 T는 아직 알려지지 않았으므로 검사를 수행 할 수 없습니다. 구체적인 T는 MyClass<T>
의 필드 또는 변수가 코드의 다른 곳에서 선언 될 때 알려져 있습니다.
가장 좋은 옵션은 어프로치를 instance-scoped으로 만들고 대상 클래스의 각 인스턴스에 대해 런타임에 유효성을 검사하는 것입니다. 아래에서이 접근법의 샘플 구현을 찾을 수 있습니다.
[PSerializable]
public class LogMethodAttribute : OnMethodBoundaryAspect, IInstanceScopedAspect
{
private bool disabled;
public override void OnEntry(MethodExecutionArgs args)
{
if (!this.disabled)
{
Console.WriteLine("OnEntry: {0}({1})", args.Method.Name, args.Arguments.GetArgument(0));
}
}
public object CreateInstance(AdviceArgs adviceArgs)
{
LogMethodAttribute clone = (LogMethodAttribute) this.MemberwiseClone();
Type type = adviceArgs.Instance.GetType();
if (type.IsGenericType)
{
Type[] genericArguments = type.GetGenericArguments();
// Filter out targets where T is string.
if (genericArguments[0] == typeof(string))
{
clone.disabled = true;
}
}
return clone;
}
public void RuntimeInitializeInstance()
{
}
}
class Program
{
static void Main(string[] args)
{
var obj1 = new Class1<int>();
obj1.Method1(1);
var obj2 = new Class1<string>();
obj2.Method1("a");
}
}
[LogMethod(AttributeTargetElements = MulticastTargets.Method)]
public class Class1<T>
{
public void Method1(T a)
{
}
}