c# - 使用 PostSharp 在 c# 中的构造函数上应用方面

标签 c# postsharp aop aspect

我正在研究 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; 使用系统文本; 使用 PostSharp.Aspects; 使用系统反射;

命名空间 MyProviders { 公共(public)类 TraceAspectProvider : IAspectProvider { 只读 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)

等待您的解决方案和回复

最佳答案

我认为您的主要问题是您正在尝试在第 3 方库 (mscorlib) 上应用方面。你可以看看Dustin's blog post on how to do this这可能会帮助你。请正式考虑到 PostSharp 不支持此功能。

为了将方面应用于构造函数,您可以使用 TypeLevelAspect和一个 MulticastPointcutits Targets set to e.g. InstanceConstructor .

当您不能使用 TypeLevelAspect 时(例如,您想将方面应用到事件)我之前使用了 OnMethodEntryAdvice和一个 MethodPointCut .这允许您手动搜索构造函数。

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

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

更广泛的讨论我如何应用它来从构造函数初始化事件 can be found on my blog .

该类最新完整源码can be found on github .自博文发布以来,我做了一些更改,但针对构造函数的原则保持不变。

关于c# - 使用 PostSharp 在 c# 中的构造函数上应用方面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12798391/

相关文章:

erlang - Elixir 编译时代码注入(inject)/AOP

c# - 如何在 C# 中将 XML 子元素添加到简单数据类型

c# - 使用 PostSharp Toolkit 构建在 4.5.1 上失败但适用于 4.5

c# - 您能否将扩展方法的范围限制为具有特定属性的类?

java - spring-aop 是否可以抛出检查异常?

java - 在aspectj类中的哪里编码ThreadLocal.remove()

c# - Object、Dynamic 和 Var 之间的区别

c# - 无法部署 Razor Pages 网站

c# - 如何将位图转换为图像

c# - 我在程序集 "Cannot serialized the aspects: Type ' 中得到 'log4net...' log4net.Core.LogImpl' - 我怎样才能让它序列化?