2012-10-09 1 views
3

Je travaille sur différents concepts dans PostSharp.Application de l'aspect sur le constructeur dans C# en utilisant PostSharp

Mise à jour:

Ceci est ma classe de programme

namespace myconstructor 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      createfolder(); 
      streamfolder(); 
     } 
     public static void createfolder() 
     { 
      File.Create("E:/samplefile.txt"); 

     } 
     public static void streamfolder() 
     { 
      StreamWriter sw = new StreamWriter("E:/samplestream.txt"); 
     } 
    } 

} 

et ma classe d'aspect comme

1) une classe d'aspect traçage:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using PostSharp.Extensibility; 
using PostSharp.Aspects.Dependencies; 
using PostSharp.Aspects; 
using PostSharp.Aspects.Advices; 
using System.Reflection; 
using System.Linq.Expressions; 

namespace MyProviders 
{ 
    [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Event)] 
    [MulticastAttributeUsage(MulticastTargets.Event, AllowMultiple = false)] 
    [AspectTypeDependency(AspectDependencyAction.Commute,typeof(SomeTracingAspect))] 
    [Serializable] 
    public class SomeTracingAspect : EventLevelAspect 
    { 
     [OnMethodEntryAdvice, MethodPointcut("SelectConstructors")] 
     public void OnConstructorEntry(MethodExecutionArgs args) 
     { 
      args.ReturnValue = "aspectfile"; 
     } 

     IEnumerable<ConstructorInfo> SelectConstructors(EventInfo target) 
     { 
      return target.DeclaringType.GetConstructors(
         BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); 
     } 

     public override void RuntimeInitialize(EventInfo eventInfo) 
     { 
      base.RuntimeInitialize(eventInfo); 

     } 
    } 

} 

2) TraceAspectProvid classe er:

en utilisant System; en utilisant System.Collections.Generic; en utilisant System.Linq; en utilisant System.Text; en utilisant PostSharp.Aspects; en utilisant System.Reflection;

MyProviders espace de noms { public class TraceAspectProvider: IAspectProvider { readonly SomeTracingAspect aspectToApply = new SomeTracingAspect();

public IEnumerable<AspectInstance> ProvideAspects(object targetElement) 
    { 
     Assembly assembly = (Assembly)targetElement; 

     List<AspectInstance> instances = new List<AspectInstance>(); 
     foreach (Type type in assembly.GetTypes()) 
     { 
      ProcessType(type, instances); 
     } 

     return instances; 
    } 

    private void ProcessType(Type type, List<AspectInstance> instances) 
    { 
     foreach (ConstructorInfo target in type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly)) 
     { 
      instances.Add(new AspectInstance(target, aspectToApply)); 
     } 

     foreach (Type nestedType in type.GetNestedTypes()) 
     { 
      ProcessType(nestedType, instances); 
     } 

} } }

et mon fichier aspect donné que

"C:\Program Files\PostSharp 2.1\Release\postsharp.4.0-x86-cil.exe" "D:\fileaspecttest\myconstructor.exe" /p:AspectProviders=MyProviders.AspectProvider,MyProviders /p:Output="D:\fileaspecttest\myaspect.exe" 

Je reçois erreur

error PS0125: An unexpected exception occured when executing user code: System.ArgumentNullException: Value cannot be null. 
error PS0125: Parameter name: type 
error PS0125: at System.Activator.CreateInstance(Type type, Boolean nonPublic) 
error PS0125: at ^7HtKTJrYMoHj.^kfEQVEmN.^jK8C2yxJ() 
error PS0125: at PostSharp.Sdk.Utilities.ExceptionHelper.ExecuteUserCode[T](MessageLocation messageLocation, Func`1 userCode, Type[] acceptableExceptions) 

En attente de votre solution et réponses

+0

@DustinDavis pouvez-vous me fournir une solution à ce sujet? – GowthamanSS

+0

Qu'est-ce qui ne va pas avec votre approche actuelle? –

Répondre

3

Je pense que votre principal problème est que vous essayez d'appliquer des aspects sur les bibliothèques tierces (mscorlib). Vous pouvez jeter un oeil à Dustin's blog post on how to do this qui pourrait vous aider. Prenez en compte officiellement ce n'est pas pris en charge par PostSharp. Pour appliquer des aspects à un constructeur, vous pouvez probablement utiliser un TypeLevelAspect et un MulticastPointcut avec its Targets set to e.g. InstanceConstructor.

Lorsque vous ne pouvez pas utiliser un TypeLevelAspect (par exemple si vous souhaitez appliquer l'aspect aux événements), j'ai précédemment utilisé un OnMethodEntryAdvice et un MethodPointCut. Cela vous permet de rechercher les constructeurs manuellement.

[OnMethodEntryAdvice, MethodPointcut("SelectConstructors")] 
public void OnConstructorEntry(MethodExecutionArgs args) 
{ 
    ... 
} 

IEnumerable<ConstructorInfo> SelectConstructors(EventInfo target) 
{ 
    return target.DeclaringType.GetConstructors(
     BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); 
} 

Une discussion plus approfondie comment j'ai appliqué ce pour initialiser les événements du constructeur can be found on my blog.

Le dernier code source complet de cette classe can be found on github. J'ai fait plusieurs changements depuis le blog, mais le principe du ciblage des constructeurs reste le même.

+0

merci pour votre solution va vérifier et vous mettre à jour – GowthamanSS

+0

puis-je simplement remplacer votre code SelectConstructors dans [OnMethodEntryAdvice, MethodPointcut ("SelectConstructors")] avec StreamWriter afin de résoudre mon problème – GowthamanSS

+0

@GowthamanSS Je ne suis pas sûr à 100% que vous serez capable d'ajuster les arguments, je vous suggère de l'essayer, mais dans la méthode 'OnConstructorEntry()' vous définissez le code qui doit être injecté au début du constructeur. Vous pouvez accéder aux arguments du constructeur via 'args.Arguments'. –

Questions connexes