About Me

Training

Nothin But .Net Developer Bootcamp

Navigation

Search

Categories

On this page

Triggering events on UI components (WinForms)
code.google.com/p/jpboodhoo!!!
ReSharper Templates
Huge Code Drop Coming!!!!!!!
Leveraging the EventHandler delegate more effectively
DateTime Formatting with single custom format specifiers
Nothin But .Net - New York , NY ( October 22nd - 26th, 2007 )
WPF - A New Set Of Shiny Tools (and the fastest way to get upto speed on it!!)
WPF/E - Get It While It's Hot
Fun With Linq and C# 3.0

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

 Tuesday, March 03, 2009
Tuesday, March 03, 2009 3:37:00 PM (Mountain Standard Time, UTC-07:00) ( .Net 3.0 | C Sharp | Programming )

I am currently working on a large winforms application (most likely the last winforms app before I make the transition to WPF). I am writing the application in a top down fashion, which means I drive out the tests for the presenters, and then move down through the corresponding layers to get a good vertical slice of functionality. When it comes to the development of the user interface I am using a command based UI to allow me to easily drive the testing of the screens easily from a unit test. One thing that I often need to do, is cause a UI component to trigger one of its own events to see if the command in question will be triggered. In order to allow for a bit of “guidance” I wrote a class that allows me to quickly trigger events on UI components. The following code snippet shows a usage:

EventTrigger.trigger_event<Events.ControlEvents>(x => x.OnKeyPress(new KeyPressEventArgs('A')), target);

I am making use of an expression tree to determine which event I want the target control to raise. This is easily done because most (almost all) UI components in both the .Net framework and 3rd party Winforms libraries follow a convention of having a method named “OnEventName” which is usually a protected method that the control itself can call when it wants to raise its event. The EventTrigger class lives in my test utilities and for my current application I have a set of Events classes which correspond to some of the third party, and raw .net, control I want to raise events on, here is a trimmed down section of one of the events class:

public class Events

{

    public interface ControlEvents : IEventTarget

    {

        void OnEnter(EventArgs args);

        void OnKeyPress(KeyPressEventArgs args);

    }

 

    public interface FormEvents : ControlEvents

    {

        void OnActivated(EventArgs e);

        void OnDeactivate(EventArgs e);

    }

}

Again, this class lives in my test utility folder and it contains interfaces specific to control types that I want to raise events on. For each control interface, I will place the events (as needed) that I need to be able to trigger from my unit tests. There are multiple ways to get the correct method signature on these interface methods, I can use the Object Browser, Reflector, or ReSharper can generate them!! The point is, the interface contains a public method that is the identical signature for a corresponding protected method on the target control. This is really to help get intellisense about the event I want to raise along with the arguments to the method itself. This works with all component frameworks as their EventArgs classes are always made public as to be able to be consumed by the components that will be hosting them.

Let’s get to the interesting part of this. I mentioned earlier that I am an expression tree to ultimately raise the event. Let's take a look at the trigger_event method signature to get a little understanding of what it is doing:

static public void trigger_event<Target>(Expression<Action<Target>> expression_representing_event_to_raise, object target) where Target : IEventTarget

Notice I am making use of the IEventTarget interface to basically simply constrain the incoming expression to be one based on one of the interfaces that lives in the “Events” class. The first argument “Expression<Action<Target>> is an expression representing the code. The target argument is the actual control to raise the event on. Here is the entire body of the trigger_event method:

static public void trigger_event<Target>(Expression<Action<Target>> expression_representing_event_to_raise, object target) where Target : IEventTarget

{

    var method_call_expression = expression_representing_event_to_raise.Body.downcast_to<MethodCallExpression>();

    var method_args = get_parameters_from(method_call_expression.Arguments);

    var method_name = method_call_expression.Method.Name;

    var method = target.GetType().GetMethod(method_name, binding_flags);

 

    Debug.Assert(target != null,"The target to raise the event on cannot be null");

    Debug.Assert(method != null,"There is no method called {0}, on a {1}".format_using(method_name,target.GetType().proper_name()));

 

    method.Invoke(target, method_args.ToArray());

}

This is test utility code, so I am able to make a lot of assumptions about how I am going to be consuming and using it. For starters I know that the ExpressionTree coming is is going to represent a MethodCallExpression. This post is only a small intro into the amazing concept of expression trees, if they are not something you are comfortable with, there is no time like the present to start playing around with them.

With a MethodCallExpression I have access to the MethodInfo object that contains information about the target method to call (this allows me to reflectively match upto the protected method on the target I want to raise the event on:

var method_name = method_call_expression.Method.Name;

var method = target.GetType().GetMethod(method_name, binding_flags);

Once I have the actual method to invoke, it still needs to be invoked with the correct arguments:

method.Invoke(target, method_args.ToArray());

The act of getting the arguments is the interesting part to this code (and a little gentle introduction to the world of ExpressionTrees for those of you who are not using them yet). The following line:

var method_args = get_parameters_from(method_call_expression.Arguments);

method_call_expression.Arguments is actually a collection of Expressions also. If you look back at the line of code that is using this the original trigger method, we’ll decompose it so that you can get a better idea of the expression tree created to represent the call to the event:

EventTrigger.trigger_event<Events.ControlEvents>(x => x.OnKeyPress(new KeyPressEventArgs('A')), target);

  • MethodCallExpression [x.OnKeyPress(
    • NewExpression[new KeyPressEventArgs(
      • ConstantExpression(‘A’)
    • )
  • )

Expression tree are “tree based structures. This simple line of code actually constructs an ExpressionTree that consists of a:

  • MethodCallExpression
    • NewExpression
      • ConstantExpression

Here is the complete code for the get_parameters_from method:

static IEnumerable<object> get_parameters_from(IEnumerable<Expression> parameter_expressions)

{

    foreach (var expression in parameter_expressions)

    {

        if (can_handle(expression)) yield return get_value_from_evaluating(expression);

        else cannot_handle(expression);

    }

}

This method iterates over each Expression in the incoming set and attempts to expand it to an actual object value. The can_handle method simply makes use of an existing dictionary that has been populated at startup with handlers that know how to evaluate the appropriate Expression:

static EventTrigger()

{

    expression_handlers = new Dictionary<ExpressionType, Func<Expression, object>>();

    expression_handlers[ExpressionType.New] = instantiate_value;

    expression_handlers[ExpressionType.MemberAccess] = get_value_from_member_access;

    expression_handlers[ExpressionType.Constant] = get_constant_value;

}

 

The get_value_from_evaluating(expression) method is very simple, it just look into the dictionary using the NodeType of the current expression, and invokes the expression handler against the expression so that it can be evaluated:

static object get_value_from_evaluating(Expression expression)

{

    return expression_handlers[expression.NodeType](expression);

}

Lets start by looking at the simplest one of them all, the method that evaluates a ConstantExpression:

static public object get_constant_value(Expression expression)

{

    return expression.downcast_to<ConstantExpression>().Value;

}

This method explicitly casts the incoming Expression to a ConstantExpression and then returns the expressions value. In our current example, that value will be the char ‘A’.

We’ll finish up by looking at the most involved one:

static object instantiate_value(Expression expression)

{

    var new_expression = expression.downcast_to<NewExpression>();

    var args = new_expression.Arguments.Select(constructor_argument_expression => get_value_from_evaluating(constructor_argument_expression));

    return new_expression.Constructor.Invoke(args.ToArray());

}

 

In the second line we are actually evaluating each of the constructor arguments expressions one at a time and having them also evaluated by the get_value_from_evaluating method. Because of the nested nature of expression trees, depending on the type of Expression that was passed in, this handles recursive traversal of the expression.

Once all of the arguments to the constructor have been evaluated, we can then invoke the expressions Constructor (which is a ConstructorInfo) to create the item. In our example here, it will cause the creation of a new KeyPressEventsArgs with the character of ‘A’ (the character was evaluated using the ConstantExpression we discussed earlier).

When it comes to testing a new control I can just create a new nested interface in my Events class, add public versions of the protected methods that I want to invoke (along with the correct arguments) and then I’m off to the races!!

Develop With Passion

Comments [1] | | # 
 Wednesday, November 28, 2007
Wednesday, November 28, 2007 11:01:52 PM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | .Net 3.0 | Agile | C Sharp | Continuous Integration | Patterns | Programming | Tools )

I finally set up a googlecode project to host source code for the various things I have been doing over the last year. The first major significant contribution is of course the code drop that I promised a week ago now!!

The application is the start of what I hope will evolve to be a great learning resource for lots of things related to .Net development. The application does not currently cover any of the “extra” topics that I did not have time to get covered in the course. This is perfect because as request come in from people (including past students) asking how to tackle a certain problem, I will use this application as the demonstration area where I can tackle the problem, and update the code base, and you will be able to update your local copy and carry on.

I am currently in the midst of a large Smart Client application that I am hoping to be able to harvest pieces of code out and do the exact same thing except for the smart client realm. I have much more experience developing in the smart client realm and that is where I feel most comfortable, so I am looking forward to be able to do another code drop (for a different application) in a couple of months.

I am going to write up another post about the Web Application as it is built very differently from traditional .Net based web applications. In following with the theme for my courses, there are currently no 3rd party frameworks (other than log4net) that have come into play. My goal with this web app is to demonstrate to people how far we can push raw .Net. The goal being that expanding their knowledge of how to creatively leverage .Net, they will be better prepared to jump into frameworks that they may currently feel daunted by. As time goes by, I will swap pieces of the application out with components that people are asking to see meaningful samples on:

  • NHibernate
  • Castle
  • Prototype
  • JQuery
  • ..*

As the app stands right now I see it as the beginning of what will shape up to be a pretty mean machine!!

I am going to post a screencast that will show people how to get started working with the web application. For people who are eager to get going right now, here are the quick and simple steps without a lot of explanation (that will come in the next post):

  • Anonymously checkout the trunk from the google code repository using the following svn command line:
    svn checkout http://jpboodhoo.googlecode.com/svn/trunk/ jpboodhoo-read-only
  • Navigate to the checkout folder
  • Go into the build folder
  • Copy local.properties.xml.template and paste it into the same directory, then rename the copied file to local.properties.xml
  • Open up the local.properties.xml file with your favourite text editor.
  • Modify any of the settings in the file that are different on your machine.
  • Open up a command prompt and navigate to the build directory of the code.
  • type: build load.data and hit enter.
  • type: build test.all.woc
  • type: build run
  • The last task should fail (I haven’t automated everything yet)
  • Create a virtual directory called nothinbutdotnetstore that points at the following location (this location is created after you attempt to run the build run task) : ${checkoutfolder)\build\deploy\web\app
  • After successfully creating the virtual directory try the build run task again.
  • If the web browser pops up pointed at a web page (for the app) you are in business. Feel free to click through the first set of pages that are implemented (only 3 pages are currently implemented).

As far as what I have planned to implement in the web app (that is currently not implemented):

  • Build out a more extensive domain model that encompasses some more advanced scenarios of the application (especially around order processing).
  • Unit Of Work for the service layer
  • Implement a lightweight OR/M layer
  • Integrate some UI frameworks like prototype
  • Eliminate Master Pages completely and switch to a much more elegant template view pattern.
  • Introduce a more robust container (as the current one is a simple dictionary wired up in a simple procedural fashion).
  • Introduce the concepts of lifecycles for the items in the container. Right now, everything wired into the container is essentially a singleton.
  • Introduce CSS based layout for the web pages (working with a designer on this one).
  • Bring security concerns into play
  • Demonstrate how to effectively manage sessions
  • ……lots,lots,lots more!!!

Obviously I will be leaning on people checking out the code and playing around with it and submitting requests for things they would like to see.

There are a couple of things that you will immediately notice about the application:

  • Clean front controller implementation with ASPX pages as the template views. There are no code behind pages in this web application. All web requests are handled by command objects that interact with the service layer, push the details into a “ViewBag” and then choose which view to render.
  • Logical layers in the project are separated using simple folders and namespaces (not full blown projects)
  • Build automation is its own project in the solution (props to Jay Flowers for this inspiration)
  • The current container implements (CustomDependencyContainer) is very simple and is handled by a big procedural application startup task.
  • Compile time support for the database layer. A couple of classes ago I introduced the concept of a generic TableColumn<T> type. In England after introducing this concept Scott Cowan leveraged his knowledge of MyGeneration to automatically generate strongly typed table definitions that we could leverage to do mapping (trust me when I say, this is nothing like datasets). Until moving into OR/M concepts deeper this gives a good place to start as the generation of the TableDefinitions is linked to whenever the SQL files change, so you will get compile errors if column types are now mismatched etc…

There are lots of other things I could talk about, but this code really is the start of what I see being a long running conversation between myself and other people wanting to learn. In all honesty for all of the emails I have not paid attention to this year, hosting code through google will allow me to answer peoples questions in a much more meaningful way as I can point them at this site to see the implementation of the code they had questions about.

I am going to be placing all of the code for presentations that I have done for the last year as well as continue to update it with the source code that comes out of new courses that will be coming out in the new year, and the DNRTv episodes.

Once again, the application is currently in its infancy, but as people start sending in the requests I now will have a venue and example to add upon to answer questions in a much more timely fashion!!!

 

Develop With Passion!!!

 

 

Comments [15] | | # 
 Tuesday, November 13, 2007
Tuesday, November 13, 2007 1:55:06 PM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | .Net 3.0 | C Sharp | General | Tools )

Since I have been asked for these quite a few times, I thought I would oblige and give these out. You can find below the links for both my Resharper Live Templates and File templates.

Enjoy:

Comments [1] | | # 
 Sunday, November 11, 2007
Sunday, November 11, 2007 5:48:00 AM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | .Net 3.0 | Agile | C Sharp | Programming | Training )

A lot of people will probably say it is about time!! I am taking the source code that just got driven out from this last week of Nothin But .Net and I am going to make it publicly available from my blog. I am hoping to release it by the end of the week. The reason that I can’t release it yet, is that there are lots of concepts that I wanted to cover in class that I did not have time too, so I am going to spend a bit of time fleshing out the code base to include all of the concepts that were missed (by student request)

Keep in mind that Nothin But .Net is a course about fundamental software development practices with a bit of a .Net slant. Here are some of the things you will be able to see in the code base:

  • How Test Driven Development was used to drive out the functionality of screens in the application in a top down fashion
  • The benefit of using Data Transfer objects not as a marshaling tool, but as a tool to let the needs of the UI not influence unecessary changes to the domain model
  • The benefits of leveraging layered architecture
  • Why you don’t need lots of projects in your enterprise solutions if you are using an automated build (take  a look at the following screenshot to get an idea for the solution structure
  • Clean Front Controller implementation so that you can eliminate the need for messy Passive View/Supervising Controller implementations just for testability of the web form world
  • Good practices around mixing both interaction and state based testing
  • Test partitioning (integration, unit, acceptance)
  • My current project build structure
  • How to avoid the overspecification problem with interaction based testing
  • Rhino Mocks and leveraging the automocking container (thanks James for getting me hooked on this thing)
  • Fluent Interfaces
  • Build Automation
    • NAnt compilation as an effective tool for pruning dead code that studio does not show
    • NAnt as a build tool
    • NAnt as your compiler and test runner
    • Build file partitioning
      • Use of filesets
    • Machine agnostic build files through use of local property files
  • Unit Testing
    • Focusing on one thing at a time
    • Incremental testing
    • Breaking reliance on setup methods
  • MBUnit
    • Decorators used effectively
  • Design Patterns
    • Visitor
    • Factory
    • Data Transfer Object
    • Adapter
    • Proxy
    • Mapper
    • Unit Of Work (lots of people have been bugging me about this for a while)
    • Lazy Loading
    • IOC
    • Gateway (and Static Gateway)
    • Service Layer
    • Identity Map
    • Data Mapper
    • Database Gateway
    • Money
    • Null Object
    • Strategy
    • Composite
    • Command
    • Template View
    • Query Object
    • Specification
    • Domain Model
    • Separated Interface
  • Design Principles
    • Single Responsibility
    • Open Closed principle
    • Dependency Inversion Principle
    • Hollywood principle
    • Tell Don’t Ask

I am sure I am missing lots in the description above, but you get the general idea. The important thing to note, is that all of the code (except for the changes I am making this week) was driven out through the course of the one week bootcamp!!

I am going to spend a couple of days ensuring that it contains as much code as possible for an initial drop, with full end to end functionality in place.

Going forward, this code will serve as a good place for me to be able to demonstrate in a public arena, concepts that people email me and ask me questions about. This way, I won’t have to spend as much time blogging, people can send me a question about something they are having problems with, I can implement the solution in the codebase and they can see how I attacked the problem from a test first perspective.

I envision this as being a very organic application. I am going to use it as a public tool to share whatever knowledge I have with as many people as possible.

When I post the code I will make sure I post a little about the application and why I feel that it will serve as a good tool to both teach and practice.

Comments [11] | | # 
 Wednesday, July 11, 2007
Wednesday, July 11, 2007 7:29:16 AM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | .Net 3.0 | C Sharp )

If you are now coding in .Net 2.0/3.0/3.5 and are creating types that expose events. Chances are you have started leveraging the EventHandler<T> delegate that frees you from creating custom delegate signatures for events anymore. If not this post is for you. Let’s say that you want to expose an event that another object could consume. Normally you would follow these steps:

  1. Create a type that inherits from EventArgs if the event is going to propagate event specific data. This step is optional as you may not have any custom data to propagate.
  2. Create a delegate signature for the event. If you are not using a custom EventArgs derivative, then you can get away with just leveraging the EventHandler delegate that already exists in the framework.
  3. Create the type that is going to raise the event and have it declare the event using either implicit or explicit event registration.
  4. Create a method on the type that will raise the event.

In .Net 2.0/3.0/3.5 these steps can now become:

  1. Create a type that inherits from EventArgs if the event is going to propagate event specific data. This step is optional as you may not have any custom data to propagate.
  2. Create the type that is going to raise the event and have it declare the event using either the EventHandler delegate type for an event that does not propagate custom data, or leverage the generic EventHandler<T> delegate to declare an event bound to the specific EventArgs derivative you need to use. Again you can use either implicit or explicit event registration.
  3. Create a method on the type that will raise the event.

This can actually become slightly better. Instead of always creating a class that derives from EventArgs if you need to pass custom data; create a parameter object that encapsulates the information you would want to propagate in the event. This class does not need to inherit from EventArgs. Then create the following utility class:

 

public class EventArgs<T> : EventArgs { private T eventData; public EventArgs(T eventData) { this.eventData = eventData; } public T EventData { get { return eventData; } } }

This means that the 3 steps above can now be changed to:

  1. Create a parameter object that encapsulates any information you want to propagate in the event.. This step is optional as you may not have any custom data to propagate.
  2. Create the type that is going to raise the event and have it declare the event using either the EventHandler delegate type for an event that does not propagate custom data, or leverage the generic EventHandler<T> delegate, with the generic EventArgs<T> class to declare an event bound to the specific parameter object you need to use. Again you can use either implicit or explicit event registration.
  3. Create a method on the type that will raise the event.

 

So if I had a parameter object that looked like this:

public class ReportingPeriod { private DateTime start; private DateTime end; public DateTime Start { get { return start; } } public ReportingPeriod(DateTime start, DateTime end) { this.start = start; this.end = end; } }

I would be able to create a type that raises an event to propagate this data as follows (using implicit registration):

public class ReportTrigger { public event EventHandler<EventArgs<ReportingPeriod>> RunReport; }

Or using explicit registration:

public class ReportTrigger { private EventHandler<EventArgs<ReportingPeriod>> subscribers; public event EventHandler<EventArgs<ReportingPeriod>> RunReport { add { subscribers += value; } remove { subscribers -= value; } } }

Develop With Passion!

Comments [8] | | # 
 Tuesday, July 10, 2007
Tuesday, July 10, 2007 6:04:13 PM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | .Net 3.0 | C Sharp )

I may be the last one in the .Net world to find this one out!! Say you wanted to execute the following string format statement:

 

return string.Format("{0:MMMM} {0:d}-{1:d}, {0:yyy}", start, end);

The result of that format command would be: January 1/1/2007-1/7/2007, 2007. This is obviously not what I was expecting. In order to specify a single character format specifier I have to use the following:

 return string.Format("{0:MMMM} {0:%d}-{1:%d}, {0:yyy}", start, end);

Which results in the following output: January 1–7, 2007 (which is what I wanted).

Notice the use of the % format specifier prior to the single digit day format specifier. That is what I was missing. If you want to know more about how this works check out the documentation here.

Develop with passion!

Comments [1] | | # 
 Monday, June 25, 2007
Monday, June 25, 2007 3:52:19 PM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | .Net 3.0 | Agile | C Sharp | Patterns | Programming | Training )

That’s right folks. Nothin But .Net is coming to New York.

The course is going to be held at TCCIT Solutions.

 The course runs for the week of October 22nd – 26th, 2007.

Overview

Nothin But .Net is a five day boot camp that will focus on pragmatically applying .Net within the context of developing a working N-Tiered application. Registrants will learn about advanced features of .Net (2.0/3.0) as they are applied 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.

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

  • Expanding the capabilities of developing with VS.Net - Enter ReSharper (a productivity add-in for Visual Studio .Net)
  • There’s more to life than generated code
  • Automation for the developer
  • Generics ( they’re not just for collections )
  • Back to basics - Rules Of Good Object Oriented Design
  • Dependency Injection
  • Object Relational Mapping in .Net
  • Applying the dependency inversion principle
  • Domain Driven Design
  • Passive View/Supervising Controller (Model View Presenter)
  • Creating layered architectures
  • Driving out functionality and design through testing
  • Taking Control Of Databinding
  • Behavior (Test) Driven Development
  • Core design patterns applied
  • Pragmatic Productivity Tools For Developers

Although the list may look rather daunting, the majority of the bullet points will be covered during the evolutionary design and construction of the sample project.

One of the main goals of the course is to show how to effectively use behavior (test) driven development, design patterns and a solid toolset to develop a portion of a non-trivial application.

The course will allow students to pragmatically apply BDD practices as well as teach people how to utilize fundamental OO concepts and techniques that will allow for them to have cleaner, more loosely coupled architectures. It will also be an opportunity for students to see what is involved in creating applications that utilize a Rich Domain Model,and the supporting infrastructure that is required to use "Plain Old Objects".

I have successfully delivered this course several times with great success. I anticipate that people who are interested will find that this is a very unique course offering, not typical of what is being delivered in the mainstream.

Seats are limited. The course costs $3000/US for a full 5 days. The fee covers:

  • 5 (8 - 14 hour days, depending on the audience availability) of bootcamp style instruction
  • Breakfast
  • Hot Lunch
  • Book - Patterns Of Application Architecture
  • Software – ReSharper 3.0 License

If you have any questions please don't hesitate to contact me at jp@jpboodhoo.com.

To Register for the course please use the following link:

Comments [2] | | # 
 Tuesday, April 10, 2007
Tuesday, April 10, 2007 7:33:37 AM (Mountain Standard Time, UTC-07:00) ( .Net 3.0 )

For those of you who have not started looking into WPF, time to start!! Even if you don’t care about the flash and jazz of the UI bits, there are pieces in there that you might want to think about leveraging in your own applications right now. One of the things that is immediately apparent to me is the evident design work that went into the development of WPF. Some of the things I have had a chance to play with that have stuck me are:

  • Logical and Visual Trees
  • Dependency Properties
  • Routed Events
  • ICommand interface (finally I can stop rolling my own!!)
  • First class command pattern support for common UI widgets
  • Even though I am not a fan of databinding, some of the enhancements that have been brought to the table are pretty impressive:
    • CompositeCollections
    • MultiBindings
    • PriorityBindings (again, finally I can stop rolling my own!!)
  • ValidationRules and ValidationResults (again,.. you get the point)!!
  • Retained-mode graphics system!!
  • Animation

I could carry on, but I think you get the point. As a developer who errs to the side of writing custom explicit code to make the UI more maintainable, WPF brings to the table a host of features that I can leverage to mix the declarative nature of XAML, with the explicitness of writing clean well-factored code that leverages proper separation of responsibilities while also taking advantage of not needing to hand roll so much stuff that I had to do with prior versions of .Net.

If you want to get upto speed quickly on what WPF can do for you, I recommend rushing to pick up a copy of the book Windows Presentation Foundation Unleashed by Adam Nathan. The book is an awesome read, and it gives you a solid grounding in all of the root concepts that you need to GROK to utilize WPF in a practical fashion.

 

Comments [5] | | # 
 Tuesday, December 05, 2006
Tuesday, December 05, 2006 8:33:35 AM (Mountain Standard Time, UTC-07:00) ( .Net 3.0 )

Scott Guthrie just announced on his blog the public community preview of WPF/E.

If they are pitching this as a flash killer, then from first impressions (given the fact that it runs on Firefox, IE, and Safari) I would say they have taken an incredible step in the right direction.

Install it and play around with the samples. Make sure to check out the demos listed on Scott's blog.

On my machine (Windows Vista) installing the SDK did not allow me to run the samples, so I also installed the CTP of the runtime which can be found here.

Enjoy.

Comments [2] | | # 
 Thursday, December 15, 2005
Thursday, December 15, 2005 8:36:03 AM (Mountain Standard Time, UTC-07:00) ( .Net 3.0 | C Sharp )
As you already may know, Microsoft released the preview of Linq a while ago, to give developers a chance to play with some of the language features that are going to be in C# 3.0. Some of the new features that will be introduced are:

  • Extension Classes
  • Lambda Expressions
  • Language Integrated Query(LINQ)


So what does all this mean to you as a developer? Here is an example of what can be accomplished with extension classes. How many times have you found yourself writing some sort of StringUtility class in your applications? Would'nt it be nice if you could just add methods that all instances of string would be able to call? Well with C# 3.0 it looks like this:


1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Query;
5 using System.Xml.XLinq;
6 using System.Data.DLinq;
7 using NUnit.Framework;
8 using LinqMadness.Core;
9 using System.Query;
10 namespace LinqMadness.Test
11 {
12 [TestFixture]
13 public class StringExtensionTest
14 {
15 [Test]
16 public void ShouldBeAbleToReverseString()
17 {
18 Assert.AreEqual("tsaoT","Toast".Reverse());
19 }
20
21 [Test]
22 public void ShouldBeAbleToTestForPalindrome()
23 {
24 Assert.IsTrue("pop".IsPalindrome());
25 Assert.IsTrue("barcrab".IsPalindrome());
26 Assert.IsTrue("elbertandednatreble".IsPalindrome());
27 Assert.IsFalse("nonPalindrome".IsPalindrome());
28 }
29
30
31 }
32 }
As you can see from the above test class, using extension classes I have been able to dynamically add methods to any instance of a string object. How did he do that?? Look at the following code that shows how this is accomplished:

1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Query;
5 using System.Xml.XLinq;
6 using System.Data.DLinq;
7 8 namespace LinqMadness.Core
9 {
10 public static class StringExtensions
11 {
12 public static string Reverse(this string stringToReverse)
13 {
14 StringBuilder builder = new StringBuilder(stringToReverse.Length);
15 for(int i = stringToReverse.Length-1;i>=0;i--)
16 {
17 builder.Append(stringToReverse[i]);
18 }
19 return builder.ToString();
20 }
21
22 public static bool IsPalindrome(this string toCheck)
23 {
24 25 for(int i = 0;i < toCheck.Length/2;i++)
26 {
27 if (toCheck[i] != toCheck[toCheck.Length -1 -i])
28 {
29 return false;
30 }
31 return true;
32 }
33 34 }
35 }



A couple of key points to note here. Notice the use of a static class. More importantly look at the signature of one of the methods that extends string with new functionality:

public static string Reverse(this string stringToReverse)

The use of the this keyword coupled with the type argument to the method indicates that this method is a behaviour that now will belong to all string instances.

Ok, so as cool as that is, take a look at the following code that demonstrates some of the new LINQ features in C# 3.0.


1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using NUnit.Framework;
5 using System.Query;
6
7 namespace LinqMadness.Test
8 {
9 [TestFixture]
10 public class CollectionTest
11 {
12 [Test]
13 public void ShouldBeAbleToFindAllOddNumbersInList()
14 {
15 List<int> numbers = new List<int>();
16 numbers.Add(1);
17 numbers.Add(2);
18 numbers.Add(3);
19 numbers.Add(4);
20 numbers.Add(5);
21
22 Assert.AreEqual(3,numbers.FindAll(i => (i % 2) != 0).Count);
23 Assert.AreEqual(1,numbers.Min());
24 }
25
26 [Test]
27 public void ShouldBeAbleToCreateCustomType()
28 {
29 IList<Customer> customers = new List<Customer>(){newCustomer("JP","555-4444",23,"SomeAddress","Canada"),
30 new Customer("Aaron","555-4444",23,"SomeAddress","Canada")};
31
32 foreach (Customer customer in customers)
33 {
34 var customerDTO = new{customer.CustomerName, customer.Phone};
35 Assert.AreEqual(customer.CustomerName,customerDTO.CustomerName);
36 Assert.AreEqual(customer.Phone,customerDTO.Phone);
37 }
38 }
39
40 [Test]
41 public void ShouldBeAbleToUseQuerySyntax()
42 {
43 IList<Customer> customers = new List<Customer>(){new Customer("JP","555-4444",27,"SomeAddress","Canada"),
44 new Customer("APerson1","555-4444",27,"SomeAddress","Canada"),
45 new Customer("APerson2","555-4444",8,"SomeAddress","Canada"),
46 new Customer("APerson3","555-4444",6,"SomeAddress","Canada"),
47 new Customer("APerson4","555-4444",3,"SomeAddress","Canada"),
48 new Customer("APerson5","555-4444",1,"SomeAddress","Canada")};
49
50
51 IEnumerable<Customer> customersOver8 = from c in customers
52 where c.Age > 8
53 select c;
54
55 IEnumerable<Customer> customersBeginningWithA = from c in customers
56 where c.CustomerName.StartsWith("A")
57 select c;
58
59
60 IEnumerable<Customer> customersWithOddNameLength = from c in customers
61 where c.CustomerName.Length % 2 != 0
62 select c;
63
64 Assert.AreEqual(2,new List<Customer>(customersOver8).Count);
65 Assert.AreEqual(2,new List<Customer>(customersBeginningWithA).Count);
66 Assert.AreEqual(1,new List<Customer>(customersWithOddNameLength).Count);
67
68 }
69
70 [Test]
71 public void ShouldBeAbleToMultiplyUsingFold()
72 {
73 List<int> numbers = new List<int>{1,2,3,4,5,6,7};
74 int product = numbers.Fold((start,current)=> start * current);
75 Assert.AreEqual(5040,product);
76 }
77
78 [Test]
79 public void ShouldBeAbleToSum()
80 {
81 List<int> numbers = new List<int>{1,2,3,4,5,6,7};
82 int sum = numbers.Sum();
83 Assert.AreEqual(28,sum);
84 }
85
86 [Test]
87 public void ShouldBeAbleToSeeIfListsAreEqual()
88 {
89 Assert.IsTrue(new List<int>(){1,2,3}.EqualAll(new List<int>(){1,2,3}));
90 Assert.IsFalse(new List<int>(){1,2,3}.EqualAll(new List<int>(){1,2,4}));
91 }
92
93 [Test]
94 public void ShouldBeAbleToGetDistinct()
95 {
96 Assert.AreEqual(4,new List<int>(new int[]{1,2,2,3,3,4}.Distinct()).Count);
97 }
98
99
100 [Test]
101 public void ShouldBeAbleToUnionTwoSets()
102 {
103 List<int> firstSet = new List<int>(){1, 2, 3, 2, 2, 2, 4, 5};
104 List<int> secondSet = new List<int>(){4, 5, 2, 2, 3, 4, 6, 7};
105
106 Assert.AreEqual(7,new List<int>(firstSet.Union(secondSet)).Count);
107 }
108
109
110 [Test]
111 public void ShouldBeAbleToIntersectTwoSets()
112 {
113 List<int> firstSet = new List<int>(){1,2,3,3,4,5,6,7};
114 List<int> secondSet = new List<int>(){4,8,9};
115
116 Assert.AreEqual(1,new List<int>(firstSet.Intersect(secondSet)).Count);
117 }
118
119 [Test]
120 public void ShouldBeAbleToOutputSquares()
121 {
122 int numberToSquare = 0;
123 foreach (int square in Sequence.Range(1,30).Select(i => i * i))
124 {
125 numberToSquare++;
126 Assert.AreEqual(numberToSquare * numberToSquare,square);
127 }
128 }
129
130 private class Customer
131 {
132 private string customerName;
133 private string phone;
134 private int age;
135 private string address;
136 private string country;
137
138
139 public Customer(string customerName, string phone, int age, string address,string country)
140 {
141 this.customerName = customerName;
142 this.phone = phone;
143 this.age = age;
144 this.address = address;
145 this.country = country;
146 }
147
148
149 public string CustomerName
150 {
151 get { return customerName; }
152 }
153
154 public string Phone
155 {
156 get { return phone; }
157 }
158
159 public int Age
160 {
161 get { return age; }
162 }
163
164 public string Address
165 {
166 get { return address; }
167 }
168
169
170 public string Country
171 {
172 get { return country; }
173 }
174 }
175 }
176 }



I'll let you wrap your head around that one over the weekend and will dive more into the details of how it all works in a later post. If you want to be able to run the code, you will need to download and install the Linq technical preview.
Comments [1] | | #