1 / 35

Aspect-Oriented Programming with Runtime-Generated Subclass Proxies and .NET Dynamic Methods

Aspect-Oriented Programming with Runtime-Generated Subclass Proxies and .NET Dynamic Methods. eva Kühn, Gerald Fessl, Fabian Schmied Institute of Computer Languages – Space-Based Computing Group Vienna University of Technology, Austria fabian@complang.tuwien.ac.at.

savea
Download Presentation

Aspect-Oriented Programming with Runtime-Generated Subclass Proxies and .NET Dynamic Methods

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Aspect-Oriented Programmingwith Runtime-Generated Subclass Proxiesand .NET Dynamic Methods eva Kühn, Gerald Fessl, Fabian Schmied Institute of Computer Languages – Space-Based Computing Group Vienna University of Technology, Austria fabian@complang.tuwien.ac.at

  2. Aspect-Oriented Programming • “New software development paradigm for better encapsulation and separation of concerns” • Goal: Allow encapsulation of cross-cutting concerns • Concerns which don’t follow the usual object-oriented or procedural decomposition of a problem • Examples: security checks, data persistence, monitoring (method call tracing) • These often don’t fit well in object-oriented designs

  3. Aspect-Oriented Programming • Better encapsulation by augmenting existing paradigm, eg. OOP • Add new constructs for cross-cutting concerns • Base code: ordinary, object-oriented code • Deals with main (mostly functional) concerns • Aspect: encapsulates a cross-cutting concern • Influences base code • Join point: points at application runtime where aspects influence base code behavior • Introduction: static changes to base code’s type structure

  4. Current Status of AOP • Mostly research • Concepts not sharply defined • Experimental tools, research papers, still being investigated • Very slowly adopted by industry • Mostly companies doing their own AOP research as well • Mostly Java • Reference tool: AspectJ • De-facto reference implementation • JBoss AOP • Spring AOP

  5. AOP and .NET • Some .NET implementations exist • NAspect • AspectC# • Aspect.Net (presentation yesterday) • XL-AOF • But often immature, incomplete, unsupported (thesis works) • Little interest by Microsoft → industry • Until recently

  6. What’s Stopping AOP? • Concept in the flow • No clear definition, still researched • Technical immaturity • Immature, incomplete, unsupported tools • Heavyweight, awkward solutions • Difficult to install, handle, use • Skeptical users • “I don’t see what it gets me” • “It magically changes my code” • “I can’t use the tools I’m used to” • Could lightweight solutions solve these problems?

  7. Lightweight AOP • Concept in the flow • No clear definition, still researched • Technical immaturity –lightweight infrastructure needed • More mature and completed tools • Lightweight solutions • Easy to install, handle, use • Skeptical users – lightweight infrastructure helps as well • “I don’t see what it gets me” • “It relies on concepts I know” • “It’s compatible to and complements the tools I’m used to” • Concentrate on these points

  8. Proxies - A Lightweight Solution? • NAspect, Aspect#, XL-AOF use a common infrastructure: subclass proxies • Lightweight infrastructure • Good feature set for AOP • Good potential for adoption • We provide an analysis of this infrastructure in the context of aspect-oriented programming

  9. What’s an AOP Infrastructure? • To implement AOP, a tool must provide a mechanism for weaving • Aspect code is combined with base code • Can be done by a compiler, preprocessor, postcompiler • Can also be done at runtime  dynamic weaving • Static structure is changed via introduction • Dynamic behavior is changed at join points • Aspect code needs to be inserted there • Either by manipulating code or by intercepting the join points • Infrastructure implements weaving mechanism

  10. What’s a Proxy, Why a Proxy? • “A proxy P is an object which acts as a placeholder for a target object T” • Wherever T is expected, the proxy can be used instead

  11. What’s a Proxy, Why a Proxy? • “A proxy P is an object which acts as a placeholder for a target object T” • Wherever T is expected, the proxy can be used instead

  12. What’s a Proxy, Why a Proxy? • “A proxy P is an object which acts as a placeholder for a target object T” • Wherever T is expected, the proxy can be used instead • Transparently extending the target object’s behavior • Without client code noticing • This can be used for an AOP infrastructure • T is the base code • P extends the base code • Transparently intercepting object access • Invoking aspect code whenever join points are reached • P adds introduced interfaces

  13. Proxy Kinds • .NET-provided proxies: transparent proxies • Made for Remoting • Advantage: completely transparent to client code • Disadvantage: quite restricted from AOP perspective • Custom proxies: not fully transparent • Client code must use special factories to create objects • Afterwards: transparent • Two kinds • (Proxy pattern (GoF): interface proxies) • Subclass proxies

  14. Subclass Proxies • ClassP derives from T • Join Points: overrides methods • Introduction: implements additional interfaces

  15. Subclass Proxies • ClassP derives from T • Join Points: overrides methods • Introduction: implements additional interfaces

  16. Runtime-Generated SC Proxies • For dynamic weaving, proxies must be generated dynamically • Override methods part of join points • Implement interfaces for introduction • This can be done using CodeDOM or Reflection.Emit • For source code, see the paper

  17. What About Instance Data? • Aspects often coupled to base objects • Need to access instance data to implement concerns • E.g. persistence aspect • Subclasses are not allowed to access instance data • Reflection.FieldInfo.GetValue • Possible • Very slow • Solution: Dynamically create accessor methods for instance data needed by aspects • This cannot be done using classic Reflection.Emit • But it can be done using Lightweight Code Generation

  18. Lightweight Code Generation • LCG allows to create methods at runtime • Can be associated with any loaded type • Can also access private members of that type • Without needing to disable visibility checks • Needs ReflectionPermission to emit code • Methods are accessed via typesafe delegate • Much faster than Reflection

  19. Concept Analysis • Subclass proxies have positive properties regarding • Invasiveness: they don’t touch existing code • Debuggability: debugging just works as is • Implementation effort: very lightweight and easy to use • Tool compatibility: all standard .NET tools can still be used • Language support: all .NET languages work • Changeability: dynamic weaving on per-instance basis • They have negative properties as well • Restricted join point model • Factory needed for object instantiation • Performance

  20. Concept Analysis • Subclass proxies have positive properties regarding • Invasiveness: they don’t touch existing code • Debuggability: debugging just works as is • Implementation effort: very lightweight and easy to use • Tool compatibility: all standard .NET tools can still be used • Language support: all .NET languages work • Changeability: dynamic weaving on per-instance basis • They have negative properties as well • Restricted join point model • Factory needed for object instantiation • Performance ?

  21. Join Point Model

  22. Performance? • Object creation • Proxies are created here • This takes a lot of time • Milliseconds instead of nanoseconds • Proxies can be cached • Subsequential instantiations are nearly as fast as ordinary new • Method invocation • In theory: very fast • Override method • In practice: tradeoff • Easier to implement if using delegates to encapsulate base method • 50ns instead of 5ns

  23. Performance? • Realistic scenario • Many instantiations of few types • Doesn’t matter whether 5 ns or 50 ns per method call • No huge performance impact • Examples we looked at • Distributed, space-based applications • No difference observable • Bottlenecks are not object instantiation or method call times • But algorithms and resources (e.g. network time)

  24. Summary • Proxies are a lightweight way to implement AOP • Reflection.Emit • Subclass proxies work well as an infrastructure • Join points via interception, introduction via interface • Access to private data via Lightweight Code Generation • Positive and negative properties • Positive properties: dynamic, lightweight, adoptability • Negative properties: limited join point model • Use-case dependent: performance

  25. Properties of Proxy-Based AOP • Proxies are created at runtime • Dynamic weaving • Proxies are able to provide a join point model • Instantiation • Method calls • Property access • Finalization • Proxies can implement additional interfaces • Introduction • Proxying is transparent to client code/base code

  26. A Note on Introduction in C# class Dog { public void Bark(){ Console.WriteLine("Bow-wow"); } } // Aspect adds Owner property at runtime Dog dog = …; dog.Bark(); Owner o = dog.Owner;

  27. A Note on Introduction in C# class Dog { public void Bark(){ Console.WriteLine("Bow-wow"); } } // Aspect adds Owner property at runtime Dog dog = …; dog.Bark(); Owner o = dog.Owner; compile-time checked

  28. Solution for Dynamic Weaving class Dog { public void Bark(){ Console.WriteLine("Bow-wow"); } } // Aspect adds IOwnerinterface at runtime Dog dog = …; dog.Bark(); Owner o = ((IOwner)dog).Owner;

  29. Solution for Dynamic Weaving class Dog { public void Bark(){ Console.WriteLine("Bow-wow"); } } // Aspect adds IOwnerinterface at runtime Dog dog = …; dog.Bark(); Owner o = ((IOwner)dog).Owner; runtime checked

  30. Unproxied Scenario • Client code uses target object directly • This reference points to the target object • Self-calls are correctly delivered • A transparent solution should expose the same behavior

  31. Transparent Proxies • CLR automatically creates proxy object P • Client uses P transparently, P delegates to T • This reference is automatically corrected • Problem 1: self-calls are not handled by the proxy • Problem 2: introduction • Problem 3: need to inherit from ContextBoundObject

  32. Interface Proxies • Client code uses object via interface I • Proxy implements the interface, delegates to target • Problem 1: this reference points to T instead of P • Problem 2: self-calls are not detected by the proxy • Problem 3: usage only via I (not transparent at all)

  33. Subclass Proxies • ClassP derives from T, overrides methods, delegates to base implementation • This reference, self-calls are correctly handled • Problem: only virtual method calls can be join points

  34. Adoptability • Non-invasive  Reliability • Doesn’t touch my code • Uses ordinary OO mechanism (subclassing) • Tool compatibility • Debugging works • No need to switch tools • Framework-based • Finished tools • Less implementation effort • Easier to get right • Not as powerful as other AOP approaches

More Related