我的C#项目是指外部.NET程序集。我想在从项目到该程序集的每次调用周围插入锁定语句。我一直试图用PostSharp建立这个,但无法找到办法。我有外部组件的源代码,我可能通过在那里插入方面来实现我最简单的目标,但我更喜欢非侵入式解决方案,我可以保持外部组件不受影响。
我发现我可以将调用包装到外部程序集中。遗憾的是,PostSharp无法包含对抽象方法的调用,而接口成员也是抽象方法。因此,这种方法不能通过接口类型覆盖调用。
[assembly: WrappingAspect(
AttributeTargetAssemblies = "Library",
AttributeTargetExternalMemberAttributes = MulticastAttributes.NonAbstract)]
[Serializable]
internal class WrappingAspect : OnMethodBoundaryAspect {
public override void OnEntry(MethodExecutionArgs args) {
Monitor.Enter(SyncRoot);
}
public override void OnExit(MethodExecutionArgs args) {
Monitor.Exit(SyncRoot);
}
}
也许我可以在项目中包含所有引用外部程序集中类型的方法。我按照以下思路思考。但是,我无法尝试这一点,因为ReflectionSearch需要一个我目前没有的PostSharp许可证。
[assembly: WrappingAspect]
[Serializable]
internal class WrappingAspect : OnMethodBoundaryAspect {
public override void OnEntry(MethodExecutionArgs args) {
Monitor.Enter(SyncRoot);
}
public override void OnExit(MethodExecutionArgs args) {
Monitor.Exit(SyncRoot);
}
public override bool CompileTimeValidate(MethodBase method) {
return ReflectionSearch.GetDeclarationsUsedByMethod(method)
.Any(r => r.UsedType.Assembly.FullName.StartsWith("Library"));
}
}
答案 0 :(得分:2)
您是否尝试过通过XML方法添加它们?直接从PostSharp(稍微过时)docs
通过XML添加方面提供了在不修改源代码的情况下应用方面的优势,这在某些遗留项目中可能是一个优势。
答案 1 :(得分:1)
回答我自己的问题1;就在这里。这是我如何使用@Mikee建议的PostSharp配置文件。我使用了PostSharp 3.1.39。
简而言之,您可以运行PostSharp将代码编织到DLL中,而无需更改该DLL的源代码。该命令可能看起来像这样(为了便于阅读,分成多行)
postsharp.4.0-x64.exe temp\mylib.dll /P:Output=mylib.dll /NoLogo
/X:myconfig.psproj
"/P:ReferenceDirectory=$(ProjectDir) "
"/P:SearchPath=$(OutDir) "
"/P:Configuration=$(Configuration)"
"/P:Platform=$(Platform)"
"/P:MSBuildProjectFullPath=$(ProjectPath) "
/P:TargetFrameworkIdentifier=.NETFramework
此命令中的$(变量)直接来自Visual Studio,例如如果你在后期构建活动中运行它。注意Visual Studio变量中的尾部反斜杠;在结束报价之前添加额外空格是必要的预防措施。
mylib.dll是编织将完成的目标程序集。输入和输出DLL必须是两个不同的文件,因此输入位于临时文件夹中。
在我的情况下,配置文件myconfig.psproj看起来像这样:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.postsharp.org/1.0/configuration">
<Multicast xmlns:my="clr-namespace:MyApp.Aspects;assembly:MyApp">
<my:MyAspect AttributeTargetMemberAttributes="Public"/>
</Multicast>
</Project>
此配置会将MyApp程序集中的方面MyApp.Aspects.MyAspect
应用于目标程序集中的所有公共成员。可以从documentation of MulticastAttribute
要在更复杂的场景中运行PostSharp,可能需要更多配置参数。运行postsharp.4.0-x64.exe /?
会给你一个有点无用的命令行参数列表。要了解PostSharp作为Visual Studio项目的一部分运行时真正使用的参数类型,您可以这样做:
Task "PostSharp30"
的行,然后向下浏览以查找以"Connected to the pipe after XXX ms. Requesting with XX arguments"
开头的行。我为测试项目获得的参数列表比上面的最终命令要长得多。许多参数都没有必要。
警告:PostSharp的免费Express版本不支持编织迭代器方法(使用return yield
的方法)。你会收到警告。