CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jean-Paul S. Boodhoo

Develop With Passion

January 2008 - Posts

  • Explicit Strongly Typed Selective Proxies - Part 2

    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!!

    Posted Jan 30 2008, 07:27 PM by bitwisejp with no comments
    Filed under:
  • Nothin But C# v3.5 with the Igloo Coder - Edmonton, AB (March 31st - April 4th)

    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

     

    Posted Jan 30 2008, 04:32 PM by bitwisejp with 2 comment(s)
    Filed under: ,
  • Explicit Strongly Typed Selective Proxies

    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> methodsToInterceptOn) { this.interceptor = interceptor; this.methodsToInterceptOn = methodsToInterceptOn; } public void Intercept(IInvocation invocation) { if (methodsToInterceptOn.ContainsKey(invocation.Method.Name)) { interceptor.Intercept(invocation); return; } invocation.Proceed(); } }

    Selective interceptor decides whether or not to forward the call onto the associated interceptor, if the method is not in the dictionary of methods to intercept on, it bypasses the interceptor and directly forwards the call onto the item to proxy.

    Notice the user of : new Interceptor();

    This creates a new instance of whatever the interceptor type was that was specified by the AddInterceptor<Interceptor> method call back on ProxyBuilder. This works because of the generic constraint that ensured that the IInterceptor implementation also had a public no-arg constructor.

    Last but not least, you are probably curious as to how the natural syntax is enabled? Take a look at the MethodCallTrackerFactory class:

    public class MethodCallTrackerFactory : IMethodCallTrackerFactory { private ProxyGenerator proxyGenerator; public MethodCallTrackerFactory(ProxyGenerator proxyGenerator) { this.proxyGenerator = proxyGenerator; } public IMethodCallTracker<T> CreateFor<T>() { MethodCallTracker<T> methodCallTracker = new MethodCallTracker<T>(); T target = proxyGenerator.CreateInterfaceProxyWithoutTarget<T>(methodCallTracker); methodCallTracker.Target = target; return methodCallTracker; } }

    The ProxyGenerator class is supplied by Castle.DynamicProxy. I am using it to create a proxy around an interface without an actual underlying target:

    T target = proxyGenerator.CreateInterfaceProxyWithoutTarget<T>(methodCallTracker);

    Notice how after the MethodCallTracker is instantiated, it is passed in as an argument to the CreateInterfaceProxyWithoutTarget method? This method takes either a single or variable array of IInterceptor implementations. That’s right. The MethodCallTracker is itself as IInterceptor implementation. It intercepts calls on its Target property so that it can store the calls to be used in the Interception filtering process:

    public class MethodCallTracker<T> : IMethodCallTracker<T> { public T Target{get;set;} private IDictionary<string, string> methodNames; public MethodCallTracker() : this(new Dictionary<string, string>()) { } public MethodCallTracker(IDictionary<string, string> methodNames) { this.methodNames = methodNames; } public void Intercept(IInvocation invocation) { SetReturnValueFor(invocation); if (methodNames.ContainsKey(invocation.Method.Name)) return; methodNames.Add(invocation.Method.Name, invocation.Method.Name); } private void SetReturnValueFor(IInvocation invocation) { Type returnType = invocation.Method.ReturnType; if (returnType == typeof(void)) return; invocation.ReturnValue = (returnType.IsValueType ? Activator.CreateInstance(returnType) : null); } public bool CallsWereMade { get { return methodNames.Count > 0; } } public IDictionary<string, string> AllMethods() { return methodNames.Copy(); } }

    And finally, the glue that ties it all together. ProxyFactory, this class actually creates proxies instances leveraging the Castle ProxyGenerator as well as the completed InterceptorConstraintSet:

     

    public class ProxyFactory : IProxyFactory { private ProxyGenerator proxyGenerator; private IMethodCallTrackerFactory methodCallTrackerFactory; public ProxyFactory():this(new ProxyGenerator(),new MethodCallTrackerFactory(new ProxyGenerator())) { } public ProxyFactory(ProxyGenerator proxyGenerator, IMethodCallTrackerFactory methodCallTrackerFactory) { this.proxyGenerator = proxyGenerator; this.methodCallTrackerFactory = methodCallTrackerFactory; } public IMethodCallTracker<T> CreateMethodCallTracker<T>() { return methodCallTrackerFactory.CreateFor<T>(); } public T CreateProxyUsing<T>(T instance, IInterceptorConstraintSet constraints) { return proxyGenerator.CreateInterfaceProxyWithTarget<T>(instance, constraints.AllInterceptors<T>()); } }

    People ask me why I love TDD? It’s because you can start with a blank slate, drive out the components one at a time in isolation from another, isolating/deferring responsibilities as you go, and finally you can plug all of the pieces together. In all of the code samples above I added in the poor mans dependency injection so that people could see the concretes being injected into the dependent. In the actual source code, an IOC container is being used. As when driving out the solution the interfaces were used to defer responsiblity to another object that did not exist yet. Taking this code, it would not be hard to add the pre/post/both filter also so that you could choose when specifically to apply an interceptor!! 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. I’ll leave that for another day!!

    Develop With Passion!!

    Posted Jan 30 2008, 02:19 AM by bitwisejp with no comments
    Filed under: ,
  • I see dead projects!!

    Just finished reading an excellent blogpost by Jonathan Rasmusson. I think we can all identify with a lot of the information in this post!!

    This is a good post that you can forward to your PM if you think they have a false sense of security about what is going on in their project!!

    Posted Jan 29 2008, 05:50 PM by bitwisejp with 4 comment(s)
    Filed under:
  • Nothin But .Net - Austin, TX (April 7th - 11th)

    After lots of requests, Nothin But .Net is finally coming to Austin,Texas!! I am sure that seats are going to sell out fast, so hurry and register here if you want a spot in what will surely be an amazing week of crazy coding!!

    Overview

    Nothin But .Net is a five day (intense) boot camp style course that will focus on applying .Net development best practices in the context of developing a working N-Tiered application. Registrants will learn about how to practically apply.Net as they apply it to the task of building a complete application from the UI layer all the way down to the mapping layer.

     

    WARNING!!!!

    If you are expecting to come to this course to learn about how to have VS.Net automatically generate an “application” for you, then this course is NOT for you.

    This course is all about taking control of the .Net framework and having it work the way you want. This course will place a heavy emphasis on getting back to the basics and making .Net do things the way you want it to, in a predictable and testable way.

    During the course of the week, there will be absolutely no code that gets compiled from within Visual Studio. Studio itself will be relegated to a glorified code editor. I will teach you development techniques and tools that will dramatically increase your day to day productivity as a software developer.

    This course will focus on a code centric view of application development vs. the typical databinding/designer magic covered by many typical .Net courses. You will walk away with a deep understanding of fundamental aspects of .Net and how these pieces can be used to develop and deliver enterprise scale applications.

    Core Concepts Overview

    *        Expand the capabilities of developing with VS.Net - Enter ReSharper (a productivity add-in for Visual Studio .Net)

    *        There’s more to development than code generators

    *        Automated Builds       

    *        Generics ( they’re not just for collections )

    *        Object Relational Mapping in .Net

    *        Creating layered architectures

    *        Driving out functionality and design through testing

    *        Taking Control Of Databinding

    *        Test Driven Development & Mock Objects

    *        Core Design Patterns Applied

     

    Detailed Topic Coverage Breakdown

    ·          Language Enhancements

    o    Generics

    o    Anonymous Delegates

    o    Iterators

    o    Linq

    ·          Collections

    o    Taking advantage of the collection interfaces

    o    Making use of the IDictionary<T> and IList<T> interfaces.

    o    Overcoming the limitations of the IList<T> interface

    o    Sorting, searching, and manipulating collections using generic delegates

    o    Overcoming limitations of searching with generic delegates

    o    Creating custom comparers

    ·          Events

    o    Delegates in depth

    o    Creating classes that expose events

    o    Safely publishing events

    o    Multithreading with delegates

    ·          ADO .Net

    o    Creating a Custom Object Relational mapping layer

    o    Effective uses of TransactionScope to test the mapping layer

    o    Eliminating the need for stored procedures

    o