2017-03-01 1 views
1

Dire que j'ai une classe générique:Exclure un aspect d'implémentations spécifiques d'une classe générique?

public abstract class MyClass<T> { 
    // Contents 
} 

Comment puis-je spécifier un aspect de mon exclure pour certains types de T? J'ajoute aspects dans ILes AssemblyInfo.cs, comme ceci:

[assembly: LogMethod(AttributePriority = 0, 
        AttributeTargetTypeAttributes = MulticastAttributes.Public, 
        AttributeTargetMemberAttributes = MulticastAttributes.Public, 
        AttributeTargetElements = MulticastTargets.Method)] 

Répondre

1

Il est impossible d'appliquer des arguments génériques filtrage de manière déclarative. Pour le filtrage avancé des cibles d'aspect, vous pouvez remplacer la méthode CompileTimeValidate sur votre aspect et filtrer par programme.

Cependant, même cela ne suffira pas dans le cas que vous avez décrit. Supposons que vous avez appliqué l'aspect à une méthode au MyClass<T>. À ce stade de la compilation, le T n'est pas encore connu, il n'est donc pas possible d'effectuer la vérification. Le béton T est connu lorsqu'un champ ou une variable de MyClass<T> est déclaré ailleurs dans le code.

La meilleure option que je peux voir dans votre cas est de faire l'aspect instance-scoped et de valider au moment de l'exécution pour chaque instance de la classe cible. Vous pouvez trouver l'exemple de mise en œuvre de cette approche ci-dessous.

[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) 
    { 
    } 
}