当前位置: 首页 > 编程语言 > C#

如何判断一个类是否在构建时或运行时装饰了PostSharpaspect分享

时间:2023-04-10 15:13:18 C#

表[WCFEndpoint]publicclassMyWCFEndpoint:WCFSvcBase,IMyWCFEndpoint{}其中WCFEndpoint是PostSharpOnExit和其他诊断信息。问题是开发人员有时会忘记将[WCFEndpoint]添加到新的WCF服务(编辑:其他从事代码审查的开发人员忘记提及它!)。我的目标是确保从WCFSvcBase派生的每个类都装饰有[WCFEndpoint]属性。我的计划是编写一个自动化(NUnit)测试来查找从WCFSvcBase派生的所有类,然后查看自定义属性并确认WCFEndpointAttribute在该集合中(为了便于阅读而简化):Assemblyassm=Assembly.GetAssembly(typeof(ReferenceSvc));类型[]类型=assm.GetTypes();IEnumerableserviceTypes=types.Where(type=>type.IsSubclassOf(typeof(WCFSvcBase))&&!type.IsAbstract);foreach(TypeserviceTypeinserviceTypes){if(!serviceType.GetCustomAttributes(true).Any(x=>x.GetType()==typeof(WCFEndpointAttribute))){Assert.Fail("发现错误装饰的svc!")我的问题是WCFEndpointAttribute没有出现在GetCustomAttributes(true)中——即使它派生自System.Attribute。我通过查看.NetReflector中的程序集确认了这一点。理想情况下,由于OnMethodBoundaryAspect是从属性派生的,我想以某种方式将[WCFEndpoint](或类似的自定义属性)“打印”到最终编译的程序集元数据中。这是迄今为止概念上最简单的答案:它在代码中可见,并且在程序集元数据中可见。有没有办法做到这一点?我发现这篇文章描述了自动注入自定义属性的TypeLevelAspect的使用,如果我可以从TypeLevelAspect和OnMethodBoundaryAspect派生WCFEndpointAttribute,它就会起作用(是的,我知道我为什么不能)。?我考虑过解决此问题的其他方法是:1)执行代码解析以确认[WCFEndpoint]是“更接近”(上面的行):WCFSvcBase。这在可维护性/稳健性方面存在明显的问题。2)通过多播自动将[WCFEndpoint]附加到从WCFSvcBase派生的所有类。我不喜欢这样,因为它在检查服务代码时混淆了PostSharp/properties的细节,尽管没有更优雅的解决方案也是可能的。3)创建一个AssemblyLevelAspect,它在构建时使用[WCFEndpoint]属性吐出所有类的列表。然后,我可以将此静态列表与通过从WCFBaseSvc派生的反射生成的类列表进行比较。AssemblyLevelAspect细节在这里。我还应该指出,我仅限于PostSharp的免费/快速版。我可以通过在切面定义中包含PersistMetadata=true来保留WCFEndpoint属性:WCFSvcBase,IMyWCFEndpoint{[WCFEndpoint]静态MyWCFEndpoint();[WCFEndpoint]公共MyWCFEndpoint();[WCFEndpoint]publicvoidEndpointFn1();[WCFEndpoint]publicvoidEndpointFn2();}WCFEndpointAttribute存储在元数据中定义是publicWCFEndpointAttribute(){}从这里,我可以将验证规则调整为“如果派生自WCFSvcBase的类中的至少一个方法具有WCFEndpoint属性,则验证通过;否则失败。"验证代码变为IEnumerableserviceTypes=types.Where(type=>type.IsSubclassOf(typeof(WCFSvcBase))&&!type.IsAbstract);foreach(TypeserviceTypeinserviceTypes){varmembers=serviceType.GetMembers();if(!members.Exists(member=>member.GetCustomAttributes(true).Any(attrib=>attrib.GetType()==typeof(WCFEndpointAttribute)))){Assert.Fail("发现错误装饰的svc!")}}I当然没有意识到OnMethodBoundaryAspect正在向所有成员(私有、公共、静态等)进行多播,尽管事后看来这肯定是有道理的。我可能最终会创建一个包含类的TypeLevelAspect的复合方面和成员的OnMethodBoundaryEntry方面(这样我就可以查找所有类),但是这个元数据足以解决我眼前的问题。感谢大家帮助缩小范围!如果你的WcfEndpoints真的需要使用Aspect编织,你可以:Postsharp有一个叫做ProgrammaticTipping的功能,你可以用C#编写一个程序来描述在哪里添加方面。将其中之一添加到您的构建工具链中,完全忘记[WCFEndpoint]属性,让您有更多时间进行编码。C#学习教程:如何确定构建位置或是否使用PostSharp在运行时修改类共享的所有内容就这些了。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:

最新推荐
猜你喜欢