使用PostSharp在C#中的构造函数上应用方面 [英] Applying aspect on constructor in c# using PostSharp

查看:192
本文介绍了使用PostSharp在C#中的构造函数上应用方面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究PostSharp中的各种概念.

I am working on various concepts in PostSharp.

已更新:

这是我的程序类,

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");
        }
    }

}

和我的方面类为

1)一些跟踪方面类:

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)TraceAspectProvider类:

使用系统; 使用System.Collections.Generic; 使用System.Linq; 使用System.Text; 使用PostSharp.Aspects; 使用System.Reflection;

using System; using System.Collections.Generic; using System.Linq; using System.Text; using PostSharp.Aspects; using System.Reflection;

命名空间MyProviders { 公共类TraceAspectProvider:IAspectProvider { readonly SomeTracingAspect AspectToApply = new SomeTracingAspect();

namespace MyProviders { 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);
        }

} } }

} } }

我的外观文件为

 "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"

我收到错误消息

 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)

等待您的解决方案和响应

Waiting for your solution and responses

推荐答案

我认为您的主要问题是您正在尝试在第3方库(mscorlib)上应用方面.您可以查看达斯汀(Dustin)关于如何执行此操作的博客文章,这可能会对您有所帮助.请正式考虑到PostSharp不支持的功能.

I think your main problem is you are trying to apply aspects on 3th party libraries (mscorlib). You can take a look at Dustin's blog post on how to do this which might help you out. Do take into account officially this isn't supported by PostSharp.

为了将方面应用于构造函数,您可能可以使用

In order to apply aspects to a constructor you can probably use a TypeLevelAspect and a MulticastPointcut with its Targets set to e.g. InstanceConstructor.

当您不能使用TypeLevelAspect时(例如,您要将方面应用于事件),我以前使用过

When you can't use a TypeLevelAspect (e.g. you want to apply the aspect to events) I previously used a OnMethodEntryAdvice and a MethodPointCut. This allows you to search for the constructors manually.

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

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

我将如何应用它来初始化构造函数

A more extended discussion how I applied this to initialize events from the constructor can be found on my blog.

此类的最新完整源代码

The latest complete source code of this class can be found on github. I've made several changes since the blog post, but the principle of targeting constructors remains the same.

这篇关于使用PostSharp在C#中的构造函数上应用方面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆