I am concerning about the performance impact by using PostSharp and Spring.NET in a big .net project (with about half million active users).
Basically I want something like this: I don't want to generate logging for half millions times when I create a user report. But when a user uses the system, I want to log some his开发者_如何转开发/her activities. Most of AOP tools just don't have this flexibility.
Is there a way to attach aspects to individual objects? Or turn an aspect on or off at runtime?
My understanding for PostSharp and Spring.NET is that you define your aspects, pointcuts, or whatever to your class at design time. There is not much you can do when you use an object of the class in terms of turning aspects on or off, or changing pointcuts, etc.
You get what you defined at class design time. No matter you use one object, or a million objects of the class. You should be very careful to use them. Otherwise, you may shoot yourslef in the foot.
What you really want is an AOP tool that addressing aspects at object level instead of class level. There is an article Add Aspects to Object Using Dynamic Decorator.
To me, Aspects are system requirements. System requirements are operational requirements and are best addressed at object level at runtime when objects are used.
To be honest, I don't understand why most of AOP tools try to address system requirements at class level at desing time. It may explain why their adoption is still so limited after so many years.
aop-logging-issues Performance overhead for logging depends how it is done.
I suppose you want to aop inject logging advices into you code. dynamic aop is only possible
- for virtual methods and
- for interfaces.
So probably you need compiletime aop.
I donot know how post-sharp does aop. with compiletime linfu-aop every method gets a pre- and a post-execution where dynamiclally is decided if and which aop-aspects are executed. this trick actualy removes the restrictins on non-virtual methods making them pseudo-virtual.
I prefer to do manuall( = non-aop-) logging with common.logging that uses the log4.net provider. This solution has minimal runtime oberhead if logging is disabled. Enabling/disabling logging can be done selecitvely without recompilation- its just a config-file that might say "all datalayer activity with sql" but not "the sql in module xyz".
Costly stacktrace-analysis (which class am i and is logging on or of for me in debug/trace,Info,....) is done only once per class.
Disabled loggings can be redured to one cheap variable boolen evaluation plus one if. This speed for size optimisation can be handled by the
logger.Debug(m => m("... costly string formatting "));
syntax that is compiled to something similar to
if (logger.IsDebugEnabled)
call anonymous method that does
the expensive string formatting
Performance of PostSharp and Spring.NET can't be discussed together. PostSharp uses compile-time weaving and Spring.NET uses runtime weaving. It means that PostSharp adds AOP overhead at compile time only and Spring.NET at runtime only - read some articles from SharpCrafters to get more insight.
About attaching aspects - one of key features of AOP are pointcuts. Pointcuts can be thought as predicates that choose whether to enable aspect for given type/method etc. So you can always create type structure and pointcuts to use logging aspect only on specific points of your system - this is just how AOP works.
About turning on/off aspects at runtime - for PostSharp, which is compiled into your code, I believe it is not possible without any tricks. For Spring.NET it will be easier, but still I don't see the point why would you need it.
I actively work on NConcern .NET AOP Framework, a new open source project with good performance. This runtime AOP Framework can inject code on non-virtual method (static included) and can be attached or detached at runtime.
Most of existing AOP Frameworks are based on same interception technic.
- Proxy (decorator with reflection) or ContextBoundObject/RemotingRealProxy for runtime implementation
- IL rewriting on post-compilation for compile time AOP Frameworks.
That's why it is an easy way to conclude on limitations and performances about Runtime vs Compile-Time implementations.
However, this is not a fatality and AOP Framework can be implemented using exclusive injection technic and modern consumer API to be very easy to use and efficient.
My implementation work at runtime and has only few limits, keeping very low coupling and offer built-in expression tree to define advice to keep maximum performance by avoiding Reflection overhead.
Please take a look on, I am interested in your opinion on the subject. It can help me to improve the product.
精彩评论