一种方法的多个方面
在我的应用程序中,我之前使用常规 C# 属性来“注释”方法。例如:
[Foo(SomeKey="A", SomeValue="3")]
[Foo(SomeKey="B", SomeValue="4")]
public void TheMethod()
{
SpecialAttributeLogicHere();
}
SpecialAttributeLogicHere() 所做的是反思性地查看注释此特定方法的所有 Foo 属性。然后,它会(自行)为所有键和值创建自己的字典。
我现在尝试转向 PostSharp,因为 SpecialAttributeLogic 可以放入 OnEntry 中的一个方面(并从方法体中删除,这更干净!)。 Foo 将被扩展 OnMethodBoundaryAspect 的方面所取代。
我仍然想按以下方式使用它:
[Foo(SomeKey="A", SomeValue="3")]
[Foo(SomeKey="B", SomeValue="4")]
但是如果 Foo 有一个 OnEntry,这意味着“SpecialAttributeLogic”将被执行两次。我基本上需要将每个 Foo() 中的所有键和值“收集”到一个字典中,然后应用一些逻辑。
如何使用 PostSharp 做到这一点(或最佳实践)?谢谢!
In my application I previously used regular C# attributes to "annotate" a method. E.g.:
[Foo(SomeKey="A", SomeValue="3")]
[Foo(SomeKey="B", SomeValue="4")]
public void TheMethod()
{
SpecialAttributeLogicHere();
}
What SpecialAttributeLogicHere() did, was to reflectively look at all the Foo-attributes that annotated this particular method. It would then (on its own), create its own dictionary for all the keys and values.
I'm now trying to move to PostSharp, because the SpecialAttributeLogic could be put into an aspect (and removed from the method body which is much cleaner!), within OnEntry. Foo will be replaced by an aspect that extends OnMethodBoundaryAspect.
I would still like to use it the following way:
[Foo(SomeKey="A", SomeValue="3")]
[Foo(SomeKey="B", SomeValue="4")]
But if Foo has an OnEntry, that means that the "SpecialAttributeLogic" will be executed twice. I basically need to "gather" all the keys and values from each Foo(), into a dictionary, which I then apply some logic to.
How to do this (or best practices) with PostSharp? Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看起来您想在方法内部构建一个名称值对。你不能用一个方面来做到这一点。我建议您使用 MethodInterceptionAspect 并反映方法上的属性,然后构建集合并通过参数(可能使用重载方法)将其传递到方法中或将其设置为类成员。
您可以在编译时反映这些值,以保持最佳性能。
这是解决您问题的快速方法。它有点难看(您需要进行修改才能适应)。还有其他方法,但它们并不那么“通用”。
目标和值都在编译时(而不是运行时)初始化,以便在运行时使用。它们在编译时通过方面进行序列化。这样您就可以节省运行时的反射命中。
It looks like you want to build a namevaluepair inside of your method. You cannot do this with an aspect. What I suggest is you use a MethodInterceptionAspect and reflect the attributes on the method then build your collection and pass it in the the method via a parameter (maybe using an overloaded method) or setting it as a class member.
You can reflect the values at compile time as to keep performance optimal.
Here is a quicky solution to your problem. It's a bit ugly (you will need to make modifications to fit). There are other ways but they aren't as "generic".
target and values are both initialized at compiletime (not runtime) for consumption at runtime. They get serialized with the aspect at compiletime. This way you save on the reflection hit at runtime.
需要注意的是,我最终使用了 MethodInterceptionAspect 并且只重写了 OnInvoke。在 OnInvoke 中,我查看了 args.Method.GetCustomAttributes(),给出了我设置的所有 System.Attributes(即 DustinDavis 示例中的 SpecialAttribute)。
使用这些属性及其属性,我可以运行我需要运行的逻辑。如果逻辑成功,我会以 args.Proceed() 结束,如果没有,我会抛出异常。
Just as a note, I ended up using MethodInterceptionAspect and only overriding OnInvoke. Within OnInvoke I looked at args.Method.GetCustomAttributes(), giving me all the System.Attributes that I set (i.e. SpecialAttribute in DustinDavis' example).
Using those attributes and their properties, I can run the logic I needed to run. If the logic succeeds, I finish off with args.Proceed(), if not I throw an exception.