Training

Nothin But .Net Developer Bootcamp

Navigation

Search

Categories

On this page

Explicit Strongly Typed Selective Proxies - Part 2
Nothin But C# v3.5 with the Igloo Coder - Edmonton, AB (March 31st - April 4th)
Explicit Strongly Typed Selective Proxies
I see dead projects!!
Nothin But .Net - Austin, TX (April 7th - 11th)
WPF UI Automation Testing With MbUnit
Dream Big, Take Some Risks, Reap the Rewards
Introducing Nothin But WPF - New York, NY (March 24th - 28th, 2008)
Nothin But * Course Schedule
If You Feel Like Hearing Me Blab For A While
Nothin But Agile Project Management - March 3rd-6th (Calgary,AB)
Happy New Year

Archive

Blogroll

 Agile Developer Venkat's Blog
 Ayende @ Blog
 B#
 Barry Gervin's Software Architecture Perspectives
 Boy Meets World
 Brad Abrams
 Canadian Developers
 Christopher Steen
 Claritude Software News
 Clemens Vasters: Enterprise Development and Alien Abductions
 Coding Horror
 Coding in an Igloo
 Dare Obasanjo aka Carnage4Life
 Darrell Norton's Blog [MVP]
 David Hayden [MVP C#]
 Don Box's Spoutlet
 Eric Gunnerson's C# Compendium
 EZWeb guy: Jeffrey Palermo [C# MVP]
 Fear and Loathing
 Generalities & Details: Adventures in the High-tech Underbelly
 Greg Young [MVP]
 Greg's Cool [Insert Clever Name] of the Day
 IanG on Tap
 Ingo Rammer's Weblog
 ISerializable - Roy Osherove's Blog
 James Kovacs' Weblog
 Jason Haley
 Jean-Luc David
 Jeremy D. Miller -- The Shade Tree Developer
 JetBrains .NET Tools Blog
 Jimmy Nilsson's weblog
 John Bristowe's Weblog
 John Papa [MVP C#]
 Jon Skeet's Coding Blog
 JonGalloway.ToString()
 Jump the Fence or Walk Around
 Lambda the Ultimate - Programming Languages Weblog
 Larkware News
 Lutz Roeder
 Marquee de Sells: Chris's insight outlet
 Martin Fowler's Bliki
 Mike Nichols - SonOfNun Technology
 MSDN Magazine - .NET Matters
 MSDN Magazine - All Articles
 OdeToCode Blogs
 Onion Blog
 Planet TW
 Raymond Lewallen [MVP]
 Rockford Lhotka
 RodMan's Corner
 Roger Johansson's blog
 Sahil Malik - blah.winsmarts.com
 Sam Gentile's Blog
 Scott Bellware [MVP]
 Scott Hanselman's Computer Zen
 ScottGu's Blog
 secretGeek
 Service Station, by Aaron Skonnard
 Signum sine tinnitu--by Guy Kawasaki
 Stephen Toub
 Steve Eichert's Blog
 Steven Rockarts
 The Blog Ride
 The Coding Hillbilly
 The Daily WTF
 TheServerSide.net: News
 Tim Gifford
 Vance Morrison's Weblog
 you've been HAACKED

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

RSS 2.0 | Atom 1.0 | CDF

Send mail to the author(s) E-mail

Total Posts: 337
This Year: 62
This Month: 13
This Week: 3
Comments: 889

 Wednesday, January 30, 2008
Wednesday, January 30, 2008 7:27:34 PM (Mountain Standard Time, UTC-07:00) ( C# )

This is a very short post to demonstrate the concept that I mentioned in parting during the last post.

“And of course I could eliminate the method call tracker altogether if I made use of lambda expressions and parsed the expression tree to see what method was called”

Someone fired an email asking how to do this so I thought I would quickly implement to show them the result. You can now also set filters on the interceptor by use of a lambda expression. So instead of this (and you can still do this):

IInterceptorConstraint<IAnInterface>constraint = sut.AddInterceptor<SomeInterceptor>(); constraint.InterceptOn.OneMethod();

or this: 

IInterceptorConstraint<IAnInterface> constraint = sut.AddInterceptor<SomeInterceptor>(); constraint.InterceptOnMethods(constraint.InterceptOn.ValueReturningMethodWithAnArgument(1));

You can now use a lambda expression which negates the need to store a reference to the constraint to apply constraints:

sut.AddInterceptor<SomeInterceptor>() .InterceptCallTo(x => x.OneMethod()) .InterceptCallTo(x => x.SecondMethod());

The InterceptCallTo method accepts an ExpressionTree of type Action<T> where T is the target to be proxied. The code to parse this expression tree into a method call is very simple. The InterceptorConstraint class just forwards the call onto its MethodCallTracker:

public IInterceptorConstraint<Target> InterceptCallTo(Expression<Action<Target>> expression) { callTracker.AddCallInferredFrom(expression); return this; }

Notice that the method returns the InterceptorConstraint itself, which is what allows for the very limited fluent interface. As far as parsing the expression to store the method to be intercepted on, it is all done by the MethodCallTracker itself: 

public void AddCallInferredFrom(Expression<Action<T>> expression) { MethodCallExpression methodCallExpression = expression.Body as MethodCallExpression; if (methodCallExpression != null) AddCallFor(methodCallExpression.Method.Name); }

That’s it, that’s all. The AddCallFor method is now called from both here and the original Interception tracker to store the list of methods that should be intercepted on.

Develop with Passion!!

Comments [0] | | # 
Wednesday, January 30, 2008 4:31:58 PM (Mountain Standard Time, UTC-07:00) ( C# | Training )

Another awesome course is entering the lineup for the March timeframe also. Unlike Wendy’s kick butt WPF course which is occuring in New York in the month of March, this course will be a Canuck affair, to be held in the winter wonderland of Edmonton!!

Donald Belcham (aka. Igloo Coder) will be the instructor for the course, and he has a crazy week lined up for the people interested in stepping up for the challenge.

You can register for the course here. Sign up quick, as seating is limited. Here is a description of the course:

Overview

Nothin’ But C# v3.5 is a 5 day boot camp styled course that provides in depth training in the new language features in version 3.5 of the .Net Framework.  Attendees will work with the new features in this version of the Framework to gain an understanding of their operation at a very deep level and aid them in the pragmatic implementation of these tools in their daily development.

While learning to use the new features of .Net v3.5, the students will also be introduced to foundational object oriented programming techniques.  They will learn both how to implement these techniques as well as understanding the benefits that they offer.

By the end of the course you will have knowledge of the new features at a very detailed level.  You will understand the concepts behind their existence, the limitations that they have and how you can use them to write better code in real applications.  None of the concepts will be taught using wizards, drag and drop or templates.  Attendees will be learning how to implement these language features combined with OO best practices and using techniques such as TDD.

Attendees should have a good understanding of programming in .Net and OO practices.  This is not an introductory course for learning to program with .Net.

Core Concepts Overview

  • New language features in .Net 3.5
  • Extension Methods – helping to make fluent interfaces
  •  Lambda Expressions – from refreshers on delegates all the way to the lean lambda
  •  Linq – for SQL, XML, Objects, etc.
  • New User Interface Controls
  •  ASP.NET MVC
  • Object Oriented Foundations

Detailed Topic Coverage Breakdown

·          New Language Features

o    Simple Properties

o    Anonymous Constructors

o    Anonymous Types

o    DateTime2

o    TimeZoneInfo

o    HashSet<T>

o    Active Directory Integration

o    Diagnostics

o    Cross Framework compatibility

·          Extension Methods

o    Using with primitive types

o    Using with complex types

o    Using with enumerations

o    Using to build fluent interfaces

o    How they are interpreted by the compiler

o    Dangers and code smells

·          Lambda Expressions

o    Refresher on Delegates

o    Refresher on Anonymous Delegates

o    Refresher on Predicates

o    Learn the syntax

o    Replacing Anonymous Delegates with Lambdas

o    How are they interpreted by the compiler

·          Linq

o    Linq fundamentals

o    How is Linq interpreted by the compiler

o    Linq to SQL

o    Linq to XML

o    Linq to Objects

o    Linq to Dataset

o    Linq and performance

·          UI Components

o    ListView control

o    DataPager control

·          ASP.NET MVC

o    MVC fundamentals

o    Writing Views

o    Routing

o    Plugging in Inversion of Control containers

o    Testability

·          Object Oriented Foundations

o    Single Responsibility Principle

o    Separation of Concerns

o    Design by Contract

o    Dependency Injection and Inversion of Control

o    Design Patterns

 

Target Audience

This is an intermediate level course that will prepare developers to work with the release of the .Net 3.5 framework.  Attendees should have a working knowledge of .Net and knowledge of the following

  •         Core working knowledge of either Visual Basic or C#
  •         Base grasp of Object Oriented Design principles
  •         High level understanding of SQL Server and XML

Intended Outcomes

Once attendees have completed this course they should have a strong, practical understanding of the following:

 

  • New base language features in the .Net 3.5 framework
  • Lambda expressions
  • Linq for SQL, XML and Objects
  • Extension methods
  • ASP.NET MVC
  • Design by contract
  • Practical application of basic patterns
  • Test Driven Development

 

About The Coordinator

Donald Belcham is a software developer with a strong focus on .NET development platforms.  He has been building application with .NET since the release of version 1.1 of the framework.  More recently Donald has become very active in the developer community as the President of the Edmonton .NET User Group.  The combination of that role and a passion for bettering the skills of any software developer, Donald has become a regular speaker at User Groups, Code Camps and conferences across North America.  He advocates and speaks on the creation of a solid set of foundational object oriented skills and understandings that can then be used with any of the many appropriate tools.  These activities and beliefs have garnered Donald a Microsoft MVP award in C#.

Donald can be reached at donald.belcham@igloocoder.com and via phone at 780.974.5860.  He welcomes open and frank conversations on different development techniques at his website www.igloocoder.com

Once again, you can register for the course here. If you have any questions do not hesitate to contact me at jp@jpboodhoo.com

 

Comments [0] | | # 
Wednesday, January 30, 2008 2:19:04 AM (Mountain Standard Time, UTC-07:00) ( C# )

Had the question the other day:

“How could I dynamically create a proxy around an object (interface based proxies are not a problem) and then selectively apply interceptors at a method by method level if necessary”.

Let’s clear up a bit of terminology so that everyone is on the same page with regards to the problem at hand:

Proxy – An object that implements the same interface as a target object and intercepts methods calls to the target to perform some sort of pre and or post method invocation.

Interceptor – An object that can be plugged into a proxy to perform a pre/post method invocation step. Common example that most people are familiar with is a LoggingInterceptor.

Attacking the problem test first drove me down a fairly interesting path that I was pleased with for a first cut. I’ll explain the details in a minute, but examples speak a lot louder than words. I created a couple of dummy interfaces and a simple object to demonstrate the proxying/interception capabilities. It should also be noted that I am making use of Castle DynamicProxy as I feel it is an much easier barrier of entry for people who want to take advantage of creating dynamic proxies vs dropping down to the wire and leveraging Reflection.Emit classes directly (though that is something that I strongly recommend playing with a couple of times, just so you have an understanding for it). Here are the interceptors that will be used in this example:

public class SomeInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { Console.Out.WriteLine("Interception occured on method {0} with {1}",invocation.Method.Name,this.GetType().Name); invocation.Proceed(); } }

public class SomeOtherInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { Console.Out.WriteLine("Interception occured on method {0} with {1}",invocation.Method.Name,this.GetType().Name); invocation.Proceed(); } }

As you can see. Both of these interceptors are ridiculously simple. They both implement the IInterceptor interface that comes from Castle.Core, the interface itself only has one method called Intercept which is the method that will get invoked by the proxy when a method call is intercepted. Both of these classes lived in a test fixture class file, so I was not concerned with the evident duplication. Here are the interface and implementation for the item that is going to be proxies:

public interface IAnInterface { void OneMethod(); void SecondMethod(); int FirstValueReturningMethod(); int ValueReturningMethodWithAnArgument(int number); } public class SomeImplementation : IAnInterface { public void OneMethod() { Console.Out.WriteLine("Real work is being done in OneMethod"); } public void SecondMethod() { Console.Out.WriteLine("Real work is being done in SecondMethod"); } public int FirstValueReturningMethod() { Console.Out.WriteLine("Real work is being done in FirstValueReturningMethod"); return 1; } public int ValueReturningMethodWithAnArgument(int number) { Console.Out.WriteLine("Real work is being done in ValueReturningMethodWithAnArgument"); return 1 + number; } }

Again, substitute this interface and implementation with any interface/implementation pair that you would want to create a proxy for in your own application. With all of those, I’ll show you some usages of the final product before explaining the solution:

Scenario 1 : Intercept on all method invocations with a SomeInterceptor

[Test] public void Should_proxy_all_methods_with_some_interceptor() { IAnInterface anImplementationOfTheInterfaceToProxy = new SomeImplementation(); sut = new ProxyBuilder<IAnInterface>(); sut.AddInterceptor<SomeInterceptor>(); IAnInterface proxy = sut.CreateProxyFor(anImplementationOfTheInterfaceToProxy); proxy.OneMethod(); proxy.SecondMethod(); }

Which results in the following console output:

Interception occured on method OneMethod with SomeInterceptor
Real work is being done in OneMethod
Interception occured on method SecondMethod with SomeInterceptor
Real work is being done in SecondMethod

Notice that the interceptor was leveraged on both method calls prior to the call on the underlying item being made.

Scenario 2 : Intercept on all method invocations with multiple interceptors

[Test] public void Should_proxy_all_methods_with_multiple_interceptors() { IAnInterface anImplementationOfTheInterfaceToProxy = new SomeImplementation(); sut = new ProxyBuilder<IAnInterface>(); sut.AddInterceptor<SomeInterceptor>(); sut.AddInterceptor<SomeOtherInterceptor>(); IAnInterface proxy = sut.CreateProxyFor(anImplementationOfTheInterfaceToProxy); proxy.OneMethod(); proxy.SecondMethod(); }

Which produces the following console output:

Interception occured on method OneMethod with SomeInterceptor
Interception occured on method OneMethod with SomeOtherInterceptor
Real work is being done in OneMethod
Interception occured on method SecondMethod with SomeInterceptor
Interception occured on method SecondMethod with SomeOtherInterceptor
Real work is being done in SecondMethod 

In this scenario both of the individual interceptors were invoked on any method call to the proxied item. Ok, so that was easy, lets try the next one:

Scenario 3 : Intercept on specific method invocations with a Single interceptor:

 

[Test] public void Should_proxy_only_targeted_methods_with_a_single_interceptor() { sut = new ProxyBuilder<IAnInterface>(); anImplementation = new SomeImplementation(); IInterceptorConstraint<IAnInterface> constraint = sut.AddInterceptor<SomeInterceptor>(); constraint.InterceptOn.OneMethod(); IAnInterface proxy = sut.CreateProxyFor(anImplementation); proxy.OneMethod(); proxy.SecondMethod(); }

Which produces the following output:

Interception occured on method OneMethod with SomeInterceptor
Real work is being done in OneMethod
Real work is being done in SecondMethod 

Notice in the test above the use of the constraint that is returned from the Add method. Notice the call to the constraint.InterceptOn.OneMethod(). That is actually setting a filter to only enable the interceptor when that method is invoked on the proxy. For those familiar with Natural Mocks syntax (Rhino Mocks / TypeMock) this should look similar. It also has the nice benefit of not requiring the use of strings to specify which methods to filter on. Which means that it is also refactoring friendly. Notice that even though 2 method calls are made on the proxy, the interceptor only kicks in for the method that the constraint was configured for!!

Scenario 4 : Intercept on specific method invocations with differing interceptors:

[Test] public void Should_proxy_only_targeted_methods_with_differing_interceptors() { sut = new ProxyBuilder<IAnInterface>(); anImplementation = new SomeImplementation(); IInterceptorConstraint<IAnInterface> constraint1 = sut.AddInterceptor<SomeInterceptor>(); constraint1.InterceptOn.OneMethod(); IInterceptorConstraint<IAnInterface> constraint2 = sut.AddInterceptor<SomeOtherInterceptor>(); constraint2.InterceptOn.SecondMethod(); IAnInterface proxy = sut.CreateProxyFor(anImplementation); proxy.OneMethod(); proxy.SecondMethod(); }

Which results in the following console output:

Interception occured on method OneMethod with SomeInterceptor
Real work is being done in OneMethod
Interception occured on method SecondMethod with SomeOtherInterceptor
Real work is being done in SecondMethod 

Notice how in this example the interceptors are firing selectively for the methods that they were configured for.

Finally you can configure multiple method constraints at a time using the following syntax:

constraint.InterceptOnMethods( constraint.InterceptOn.FirstValueReturningMethod(), constraint.InterceptOn.ValueReturningMethodWithAnArgument(0));

Again, the syntax for this was heavily inspired by prolonged usage of Rhino Mocks. So let’s inspect the players that come together to make this all work:

 

public class ProxyBuilder<T> : IProxyBuilder<T> { private IProxyFactory proxyFactory; private IInterceptorConstraintSet constraintSet; public ProxyBuilder():this(new ProxyFactory(),new InterceptorConstraintSet()) { } public ProxyBuilder(IProxyFactory proxyFactory, IInterceptorConstraintSet constraintSet) { this.proxyFactory = proxyFactory; this.constraintSet = constraintSet; } public IInterceptorConstraint<T> AddInterceptor<Interceptor>() where Interceptor : IInterceptor,new() { constraintSet.AddConstraintFor<Interceptor,T>(); return constraintSet.GetConstraintFor<Interceptor,T>(); } public T CreateProxyFor<T>(T instance) { return proxyFactory.CreateProxyUsing<T>(instance, constraintSet); } }

This is entry point to the api used to create proxies and associate interceptors with them. Driving out the design in a test first manner really helped me push off responsibilities to the last possible moment. Which leaves the ProxyBuilder class fairly simple. It leverages both a ProxyFactory and an InterceptorContraintSet. The InterceptorConstraintSet is just a strongly typed collection of constraints with a little bit of smarts to it:

public class InterceptorConstraintSet : IInterceptorConstraintSet { private IDictionary<Type, object> constraints; private IInterceptorConstraintFactory constraintFactory; public InterceptorConstraintSet():this(new Dictionary<Type,object>(),new InterceptorConstraintFactory(new ProxyFactory())) { } public InterceptorConstraintSet(IDictionary<Type, object> constraints, IInterceptorConstraintFactory constraintFactory) { this.constraints = constraints; this.constraintFactory = constraintFactory; } public void AddConstraintFor<Interceptor, Target>() where Interceptor : IInterceptor, new() { if (constraints.ContainsKey(typeof(Interceptor))) return; constraints.Add(typeof (Interceptor), constraintFactory.CreateFor<Interceptor, Target>()); } public IInterceptorConstraint<Target> GetConstraintFor<Interceptor, Target>() where Interceptor : IInterceptor, new() { return (IInterceptorConstraint<Target>) constraints[typeof (Interceptor)]; } public IInterceptor[] AllInterceptors<Target>() { return SetOfAllInterceptorsFor<Target>().AsList().ToArray(); } private IEnumerable<IInterceptor> SetOfAllInterceptorsFor<Target>() { foreach (IInterceptorConstraint<Target> constraint in constraints.Values) { yield return constraint.BuildInterceptor(); } } }

The SetOfAllInterceptorsFor<Target> method is interesting as this is where the work to create the interceptors for a proxy is delegated to the constraint. The InterceptorConstraint and its accompanying collaborators is what allows for the natural syntax:

 

public class InterceptorConstraint<Target,Interceptor> : IInterceptorConstraint<Target> where Interceptor : IInterceptor,new() { private readonly IMethodCallTracker<Target> callTracker; public InterceptorConstraint(IMethodCallTracker<Target> callTracker) { this.callTracker = callTracker; } public Target InterceptOn { get { return callTracker.Target; } } public void InterceptOnMethods(params object[] makeMethodCallsUsingInterceptOnProperty) { } public void InterceptOnMethods(params Action[] makeMethodCallsToInterceptOnPropertyInsideOfActionDelegate) { foreach (Action action in makeMethodCallsToInterceptOnPropertyInsideOfActionDelegate) { action(); } } public IInterceptor BuildInterceptor() { if (callTracker.CallsWereMade) return new SelectiveInterceptor(new Interceptor(), callTracker.AllMethods()); return new Interceptor(); } }

The work of doing the interceptor filtering is done in the BuildInterceptor method. The InterceptorConstraint makes use of a MethodCallTracker which keeps track of whether calls were made to filter on selective methods. If the client is requesting a filtered interceptor the InterceptorConstraint returns an instance of a SelectiveInterceptor. SelectiveInterceptor is a proxy for an Interceptor (I know that is a mouthful!!):

public class SelectiveInterceptor : IInterceptor { private IInterceptor interceptor; private IDictionary<string,string> methodsToInterceptOn; public SelectiveInterceptor(IInterceptor interceptor, IDictionary<string, string> methodsTo