About Me

Training

Nothin But .Net Developer Bootcamp

Navigation

Search

Categories

On this page

Layering Schemes For Projects (One approach)
Tips for becoming a more effective developer
Why I love to code and teach
TDD Live
Error Accessing Outlook Address Book When Composing a Message
Take Advantage of the ?? operator
My New Favorite Blog Code Highlighter
Naming variables using the variable type name (useless tip #1)
November Speaking Schedule
If you like music!!
Applied TDD Source Code Update
My DNIC Interview
Refactoring Ahoy!!
Screencast - Applied Test Driven Development For Web Applications (Part 3)
For All You ReSharper Keyboard Junkies
Who Said Being Passive Was A Bad Thing?
Change Of Plans
Fellow Blogger Receives MVP Solutions Architect
Edmonton Code Camp Closing Thoughts

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: 519
This Year: 28
This Month: 0
This Week: 0
Comments: 1593

 Tuesday, October 31, 2006
Tuesday, October 31, 2006 9:26:10 PM (Mountain Standard Time, UTC-07:00) ( Patterns )

I was recently asked the following question in an email:

Do you know where I can find information (blog or book) on how you are setting up your Domain Object (i.e. in your demo it was Northwind.Domain)?  Is that basically where you keep your rules (i.e. if it such and such customer then give them a 10% discount)?

I took this as a question as to how to go about setting up the layers in the application. Which caused me to go on the following tangent:

The layering of a project is something that definitely falls into a personal taste category. There are also lots of well known strategies/suggestions for layering an application. Another thing to note is that there is not necessarily a one-to-one relationship between physical/logical layer and a VS project. In the example applications that I have shown I have definitely used a solution that demonstrates one physical project per layer of concern. There are definitely many times on large projects where one logical/physical layer is composed of many physical VS.Net projects.

The domain layer is where your entities, value objects, business rules, validations, and a whole host of other objects go. This is the heart of the system, and is often the place where you can drive out solutions in a test first manner to ensure that you are able to solve a particular business problem in a clean and meaningful way. For the most part, the domain layer consists of plain old objects. Saying plain does not mean that they are necessarily simple. It means that the domain should be completely oblivious to any “services” that will be required to support it in the context of the running application (mapping being one of the most well known services).

A layering scheme that I have come to use a lot is the following:

· UI (User interface components, web forms,winforms, mobile screens, consoles)

· Presentation (View interfaces, presenters, formatters, mappers (oo mappers not OR mappers), globalization)

· DTO (Data transfer objects, used for passing information between the UI, presentation, and service layers). Again, depending on the project you may not need to introduce a separate set of objects to marshal data between the presentation and service layer. You may opt instead to pass your domain objects to the presentation layer directly.

· Service (Transaction control, authorization, domain object coordination), there are definitely times when you may not want to think about utilizing a service layer. For the amount of work involved in creating a simple façade ,around your application functionality, I almost always use one.

· Data Access (O/R mapping, this layer can get pretty big if you are not taking advantage of existing O/R mappers)

· Utility (Utility classes that can be consumed and used by any layer in the application, each class follows the single responsibility principle, and great care is made to ensure classes in this layer are not just catch-alls for functionality that was not able to be placed correctly on an object in another layer.

This is a very basic layering scheme. Depending on the needs of the application, there may be more levels of indirection that are required.

Comments [8] | | # 
 Friday, October 27, 2006
Friday, October 27, 2006 8:36:19 AM (Mountain Standard Time, UTC-07:00) ( Tools )

At the last couple of presentations I have delivered I have been asked the question “How do I find the time to keep up with all this stuff?”. A lot of time I think this is a pretty funny question as the answers seem like common sense. Here is my short bullet point (with some brief descriptions) on how to maximize your development day:

  • Wake up early (shoot for 5AM if possible) – I just started at a new contract a couple of months ago, and I have definitely fallen off the wagon with this one. Our house is currently undergoing renovation so currently all 6 of us are sleeping in the same room. This has definitely thrown me off my game!! When things are normal schedule I usually try to be up at 5:00AM and hit the gym for a refreshing workout that gives me the energy I need to challenge the day head on. As a personal practice, I also try as much as possible to spend some time in the morning in prayer and reflection, giving thanks to my Lord Jesus Christ for all the blessings he has brought into my life. Starting the day early can give you an extra edge (and time) when it comes down to fitting in other activities into what would seem like an impossible schedule.
  • Check your email in the morning and then turn if off – Ok, that may seem a little extreme, but it is definitely possible. I usually only check my email once or twice during a work day, and even then it is just to see whether I have anything I “need” to respond to. My mentality is, if someone really wants to get a hold of me they can give me a call.
  • MSN What? – I could probably win an award for least amount of time spent instant messaging. I am not sure why, but I have never really got into it. Occasionally I will chat with someone about a topic, but for the most part my MSN is off for most of the work day, and usually most of the day period. Again, if someone wants to talk to me they will phone me.
  • Ditch The Mouse – I concur 100% with Jeremy Millers point. There was a 2 week period in the last year where I purposefully did not attach a mouse to my laptop (my main computer). Initially it was a bit painful but I learned a whole bunch of awesome keyboard shortcuts for all sorts of apps under windows. And I have gotten to the point where it pretty much such beside my keyboard unused for most of the day. Because I spend most of my day in VS2005, ReSharper has become an invaluable addition for allowing me to achieve near mouseless computing. The keyboard is to developers what the command line is to administrators. Sure you can achieve the same result using the mouse, but you will definitely get to the end result faster if you use the keyboard (almost always).
  • Don’t be afraid of utilities – Scott Hanselman maintains his “Ultimate Tools List”. If you have not already checked it out, stop reading this and go there right now. I can guarantee that you will find utilities that will allow you to achieve greater productivity in your development day.
  • Upgrade your computer – It is no good having all the fastest utilities and IDE’s in the world if your computer can’t run them. Don’t let your computer be a bottleneck for your productivity.The cost of hardware is so cheap right now that there should be no good justification for not providing developers with the tools they need to do their job properly.
  • Strive for at least a 5 hour day – What I mean by that point is that as a developer, if you are not finishing the end of your day feeling mentally taxed, then you probably did not push yourself as hard as you could have. Too many people surf the net for a while, check email, messenger etc. If they redirected their energies into ensuring that they got a solid 5 hour coding stint in (within a 8/9 hour work day) they would definitely leave work feeling a lot more satisfied, with a greater sense of accomplishment.
  • Take your lunch break - Even if it just a short walk around the block to get some fresh air, you will be doing yourself a favour.
  • Pair for focus – This is not something that is applicable for everyone, but if you find that you spend a lot of idle time at your computer, find someone to pair program with and you will lose the opportunity for unnecessary down time.

That’s it for now!! I hope you find some of these practices useful.

Comments [6] | | # 
 Thursday, October 26, 2006
Thursday, October 26, 2006 10:32:10 PM (Mountain Standard Time, UTC-07:00) ( Presentations )

The other day I had the wonderful honor of providing a tailored session on test driven development, interfaced based programming, and OO design principles.

I am first and foremost a developer and I love to be in the trenches driving out complex business solutions that deliver value into the hands of clients.

I did , however, start off in the world of computers in a part time Comp Sci teaching position. One thing I learned during that brief period is how much I enjoyed helping other developers improve their own skillsets. I have been blessed to work with many talented people over the years, along the way I have managed to accumulate an extensive knowledge base that I try to share with others as time permits.

One of the main reasons I have been getting active in the developer community in the last year is to share on a larger scale with the developer community. It is an extremely refreshing experience when you can see the light go on in the eyes of a developer who realizes the value in a concept you are trying to convey.

Do I think I know it all? Absolutely not. Learning is a continuing journey. I love when I read something/ meet someone who shares a new idea with me that I was previously unaware of. I love having those humbling experiences that help keep the pride level in check!!

I wanted to share with some of my readers some comments from the developers that provided anonymous feedback to the course that I gave. Again, the biggest reason I am actively trying to share is that in a small way this is how I can give back for the blessings that I have received over the course of both my personal and professional life. Reading these comments is continual encouragement and inspiration that prompts me to push the envelope everyday, and in my small way take part in helping developers realize more satisfaction from their own jobs:

What was the best part of the presentation? How would you improve the next presentation?
I found the demonstration of OO Design practices the most helpful.  For example, the creation/use of a NullObject. 
 
More focused on one topic with the same length of presentation.
Examples are great.  For not being a 'developer', I was able to follow the examples and understand the code.  He's great! Great for me -- however was information overload for some junior people
 
That the slides where few, just to help in describing what he was going to do,  and that he showed how to do it in code building as he is explaining the concepts.
I think a few breaks might have kept the interest throughout the presentation.
Null Objects Implementing an Interface
building presentation layers (no code in UI)
I would've liked a bit more of a structured presentation.  JP also covered a lot of topics, which was good, but perhaps could've been spread out over several presentations.  I would've liked to go through the interface programming/mock objects part with a fresh mind.  I needed a couple of breaks because I just can't sit for that long at a time!
I thought the use of interfaces was interesting.  I was impressed with his knowledge and speed. Focusing only one topic in the same time span will help us fully understand.
 
live coding
 
the examples
 
I really liked the "on the fly" demos JP did to illustrate TDD.  I appreciated that he went over basic definitions and that he asked us what we knew and what we didn't know as he was going along.
 
Tying good OOD principles to TDD.  Introduced me to many new dev tools.
Interface programming / Mock Objects
Interface/Mock obj/Design pattern/OO/Development Tools
Great Overall

Comments [1] | | # 
 Wednesday, October 25, 2006
Wednesday, October 25, 2006 10:47:25 PM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | C Sharp | Presentations )

There is no better way to appreciate the effectiveness of Test Driven Development, that seeing it done real time. Today I spent a couple of hours with the good people at Focus, and was attempting to cover in a small 4 hour session:

  • Test Driven Development
  • Interface Based Programming
  • Dependency Inversion Principle – followed by Dependency Injection
  • Mock Objects

In such a short amount of time you can only hope to cover these topics at a pretty high (and quick) level.

The fun part, was coming up with a problem on the fly that I could use to demonstrate the values of Test Driven Development/Behavior Driven Development. By not going to the session with a prepared application, it allowed me to drive out a solution right before their eyes, and hopefully left them with a good impression as to the effectiveness that TDD can bring into an evolutionary design process.

 

 

Comments [2] | | # 
Wednesday, October 25, 2006 9:43:31 PM (Mountain Standard Time, UTC-07:00) ( Tools )

Since I have decided to start using my blog as a personal scratch pad.  I thought I would log this in case I needed it for future reference. I was composing a new email in Outlook 2003 and I got the following error message when I tried to add a contact from my address book:

 The address list could not be displayed. The Contacts folder associated with this address list could not be opened; it may have been moved or deleted, or you do not have permissions. For information on how to remove this folder from the Outlook Address Book, see Microsoft Outlook Help.

Of course Google to the rescue!! I found the document that helped me figure out the solution here: http://support.microsoft.com/kb/319901.

Hope this helps!!

Comments [0] | | # 
 Friday, October 20, 2006
Friday, October 20, 2006 10:41:21 AM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | C Sharp )

I stumbled onto this awesome operator after a month or 2 of working with C# 2.0 (almost 2 years ago now). Take advantage of it to make your lazy initialization a lot simpler (not worrying about thread safety here). The operator simply returns the left-hand operand if it is not null otherwise it returns the right-hand operand. Take a look at the following progression of the code:

 

Simple If Statement:

 

        public ISession ActiveSession
        {
            get
            {
                if (activeSession == null)
                {
                    activeSession = mappingSessionFactory.Create();
                }
                return activeSession;
            }
        }

 

Made tighter by eliminating the braces:

 

        public ISession ActiveSession
        {
            get
            {
                if (activeSession == null) activeSession = mappingSessionFactory.Create();                
                return activeSession;
            }
        }
 
Further condensed by taking advantage of the ternary operator :
 
        public ISession ActiveSession
        {
            get { return (activeSession == null ? activeSession = mappingSessionFactory.Create() : activeSession); }
        }
 
Made readable again by taking advantage of the ?? operator:
 
        public ISession ActiveSession
        {
            get { return activeSession ?? (activeSession = mappingSessionFactory.Create()); }
        }

 

Notice what is happening in that line? If the left hand side of the operand (the activeSession field) evaluates to null,  the right-hand operand is returned; which in this case results in an initialization of the field that was null in the first place.Again, this is not new information, I just thought I would throw it out there as a reminder.

 

JP

Comments [6] | | # 
Friday, October 20, 2006 2:03:37 AM (Mountain Standard Time, UTC-07:00) ( Tools )

For the longest time I have been using Actipro Code Highlighter to do my code highlighting for my blog posts. It is free and it does an awesome job. Lately I have been using a Live Writer plugin written by Douglas Stockwell. Now it is as easy as copy my code in visual studio and pasting it into Live Writer (with the use of a menu item).

Just download the zip file and extract it to your Windows Live Writer plugins directory, and you are off to the races. Thanks Doug.

Comments [6] | | # 
Friday, October 20, 2006 1:49:22 AM (Mountain Standard Time, UTC-07:00) ( C Sharp )

I'm not sure why you would want to do this (and I may be the last person in the world who actually figured this out), in C# if you try to do something like this it will be completely invalid:

 

            public void SomeMethod()
            {
                object object = new object();
            }
 
You can ,however, do this:
 
            public void SomeMethod()
            {
                object @object = new object();
            }
 
Notice the use of the @ symbol.
 
Again, I can't see any value in taking advantage of this, take care with using this feature!!!
Comments [1] | | # 
 Sunday, October 15, 2006
Sunday, October 15, 2006 7:34:09 AM (Mountain Standard Time, UTC-07:00) ( Presentations )

One of the things I have really enjoyed doing a lot this year has been presenting at different user groups across Canada. One of my roles as a consultant is to often give ad-hoc presentations to groups in and around the city of Calgary, introducing them to topics that they may not be particularly familiar with.

In November I will be taking part in a small MSDN Speakers Tour (I think that is what they are called) and I will be making stops in Winnipeg, Regina, and Saskatoon. The tour dates are November 6th,7th, and 8th. The main focus of the presentations will be to dive into design patterns, test driven development, and possibly patterns of enterprise application architecture.

Here is the actual schedule (times will be updated as soon as possible):

  • Regina .Net User Group - 6th November - Topic: Patterns for building an Object Relational Mapping Layer in .Net
  • Winnipeg .Net User Group - 7th November - Topic: Design Patterns - An Introduction
  • Saskatoon .Net User Group - 8th November - Topic : TBD

If you happen to be out and about (and in these cities) feel free to attend, give feedback and say hi!!

Comments [0] | | # 
 Thursday, October 12, 2006
Thursday, October 12, 2006 12:20:50 PM (Mountain Standard Time, UTC-07:00) ( Family )

This is something I should have blogged about a long time ago (although seeing how I keep my personal life very private, it should be no surprise). My amazingly talented sister has been hard at work recording songs for an album she is working on. Head over to her myspace page if you are interested in hearing some of her stuff. As well as being an incredible singer, she is also an extremely loving mother and wife!! I am very proud of her.

Request her songs on your local radio stations, and let's spread the word about her awesome music.

Comments [0] | | # 
 Wednesday, October 11, 2006
Wednesday, October 11, 2006 10:26:00 PM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | Presentations )

Thanks to the notification of Steve Nickerson, I have updated the original zip file that I released containing the source. This gets rid of a compile error that was present in the original source (I messed stuff up when I was prepping for deploying the zip)!! Download the latest code from here (the original link has been updated also).

 

Thanks Steve.

Comments [4] | | # 
Wednesday, October 11, 2006 10:23:24 AM (Mountain Standard Time, UTC-07:00) ( Presentations )

I had the awesome honor of being interviewed by John Bristowe on his great podcast Developer Night In Canada. The show was a general rant about design patterns and test driven development. The main focus was supposed to be on design patterns, unfortunately I got a little sidetracked and went on a general rant that caused the show to go much longer than its usual timeframe. If you can muddle through my blabbing I am pretty sure I was able to disperse a couple of good nuggets in there somewhere!!

Any feedback is welcome!!

Comments [0] | | # 
 Tuesday, October 10, 2006
Tuesday, October 10, 2006 2:55:48 PM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | C Sharp )

In response to Stevens' post on the Decompose Conditional refactoring, I thought I would offer up a quick alternative that I could share with others. Take a look at the code after Stevens original refactoring (I am making guesses as to the actual implementations, but it should convey pretty accurately the general idea of what is going on. I converted the code to C#, for my sanity!! 

public enum PaymentType { Cash, CreditCard } public interface IPaymentView { PaymentType PaymentType{get;} event EventHandler Save; decimal Amount{get;} void ShowMessage(string message,bool someFlag); void CloseView(); } public interface IPaymentTask { void SaveCashPayment(decimal amount); void SaveCreditCardPayment(decimal amount); } public class PaymentPresenter { private IPaymentTask task; private IPaymentView view; public PaymentPresenter(IPaymentView view,IPaymentTask task) { this.task = task; this.view = view; HookupEventHandlersTo(view); } private void HookupEventHandlersTo(IPaymentView view) { view.Save+=delegate{ ProcessPayment(); }; } public void ProcessPayment() { if (PaymentTypeIsCash()) { SaveCashPayment(); } else { SaveCreditCardPayment(); } } private bool PaymentTypeIsCash() { return view.PaymentType == PaymentType.Cash; } private void SaveCashPayment() { try { task.SaveCashPayment(view.Amount); } catch (Exception) { view.ShowMessage("There was a problem saving the payment.",false); } view.CloseView(); } private void SaveCreditCardPayment() { try { task.SaveCreditCardPayment(view.Amount); } catch (Exception) { view.ShowMessage("There was a problem saving the payment.",false); } view.CloseView(); } }

By utilizing the Decompose Conditional refactoring, he was able to make the code in the ProcessPayment method a bit more readable. Steven asked for suggestions to help further refactor the code, and I am going to offer this one tidbit. Anytime I am switching on some data and then performing some processing based on the data, it screams like a good candidate for the "Replace Conditional with Strategy" refactoring. However, I am not going to go crazy. I will offer up a similar solution, that does not require the introduction of a whole strategy hierarchy.

The goal is to eliminate the conditional completely (and also, offer up a good migration path, in the event other payment types come into play). The key to this solution is to take advantage of delegates, and the PaymentType itself. One thing we can take advantage of in this scenario is the fact that the methods to process a payment have identical signatures. Let's create a delegate that can be used to invoke both of these methods:

 

private delegate void PaymentProcessor();

 

Armed with that signature we can now do the following:

 

public class PaymentPresenter { private IPaymentTask task; private IPaymentView view; private delegate void PaymentProcessor(); private IDictionary<PaymentType,PaymentProcessor> paymentProcessors; public PaymentPresenter(IPaymentView view,IPaymentTask task) { this.task = task; this.view = view; InitializePaymentProcessors(); HookupEventHandlersTo(view); } private void InitializePaymentProcessors() { paymentProcessors = new Dictionary<PaymentType,PaymentProcessor>(); paymentProcessors.Add(PaymentType.Cash,SaveCashPayment); paymentProcessors.Add(PaymentType.CreditCard,SaveCreditCardPayment); } private void HookupEventHandlersTo(IPaymentView view) { view.Save+=delegate{ ProcessPayment(); }; } public void ProcessPayment() { paymentProcessors[view.PaymentType](); } // public void ProcessPayment() // { // if (PaymentTypeIsCash()) // { // SaveCashPayment(); // } // else // { // SaveCreditCardPayment(); // } // } // private bool PaymentTypeIsCash() // { // return view.PaymentType == PaymentType.Cash; // } private void SaveCashPayment() { try { task.SaveCashPayment(view.Amount); } catch (Exception) { view.ShowMessage("There was a problem saving the payment.",false); } view.CloseView(); } private void SaveCreditCardPayment() { try { task.SaveCreditCardPayment(view.Amount); } catch (Exception) { view.ShowMessage("There was a problem saving the payment.",false); } view.CloseView(); } }

By taking advantage of the dictionary we have removed the need for both the if statement in the ProcessPayment method, as well as the method that determines whether a payment type is cash. Each payment type will be initialized to be processed by a particular process method. If a new payment type is added, it is as simple as adding a new method for processing the payment type, and an accompanying line to the InitializePaymentProcessors method, no change would be required to the ProcessPayment method.

For one last refactoring, let's eliminate the duplication that is happening in both of the Save methods. Both methods try to call the appropriate method on the service layer, if they fail the presenter tells the view to display a message, otherwise they tell the view to close. We can consolidate that logic into the ProcessPayment method as follows:

 

public void ProcessPayment() { try { paymentProcessors[view.PaymentType](); } catch (Exception) { view.ShowMessage("There was a problem saving the payment.",false); } view.CloseView(); }

With that change in place our respective save methods become one liners:

 

private void SaveCashPayment() { task.SaveCashPayment(view.Amount); } private void SaveCreditCardPayment() { task.SaveCreditCardPayment(view.Amount); }

 

Once those methods are collapsed as such, you can also inline the method calls themselves, and eliminate the methods that are just wrapping calls to the underlying service layer. To do that we need to change the signature of our delegate to a signature that matches the methods that will get called on the underlying service layer. The final result of this refactoring results in a much tighter presenter:

 

public class PaymentPresenter { private IPaymentTask task; private IPaymentView view; private IDictionary<PaymentType,PaymentProcessor> paymentProcessors; private delegate void PaymentProcessor(decimal amount); public PaymentPresenter(IPaymentView view,IPaymentTask task) { this.task = task; this.view = view; InitializePaymentProcessors(); HookupEventHandlersTo(view); } private void InitializePaymentProcessors() { paymentProcessors = new Dictionary<PaymentType,PaymentProcessor>(); paymentProcessors.Add(PaymentType.Cash,task.SaveCashPayment); paymentProcessors.Add(PaymentType.CreditCard,task.SaveCreditCardPayment); } private void HookupEventHandlersTo(IPaymentView view) { view.Save+=delegate{ ProcessPayment(); }; } public void ProcessPayment() { try { GetPaymentProcessorFor(view.PaymentType)(view.Amount); } catch (Exception) { view.ShowMessage("There was a problem saving the payment.",false); } view.CloseView(); } private PaymentProcessor GetPaymentProcessorFor(PaymentType paymentType) { return paymentProcessors[paymentType]; } }

 

Of course, another option altogether is to offset the strategy for processing a payment off to the service layer (backed up by a rich domain model, with strategies for handling different payment types). With such a scenario in place you could end up with a presenter that looks like the following:

 

public class ProcessPaymentDTO { private decimal amount; private PaymentType paymentType; public ProcessPaymentDTO(decimal amount,PaymentType paymentType) { this.amount = amount; this.paymentType = paymentType; } public PaymentType PaymentType { get{return this.paymentType;} } public decimal Amount { get{return this.amount;} } } public interface IModifiedPaymentTask { void Process(ProcessPaymentDTO paymentToProcess); } public class ModifiedPaymentPresenter { private IModifiedPaymentTask task; private IPaymentView view; public ModifiedPaymentPresenter(IPaymentView view,IModifiedPaymentTask task) { this.task = task; this.view = view; HookupEventHandlersTo(view); } private void HookupEventHandlersTo(IPaymentView view) { view.Save+=delegate{ ProcessPayment(); }; } public void ProcessPayment() { try { task.Process(new ProcessPaymentDTO(view.Amount,view.PaymentType)); } catch (Exception) { view.ShowMessage("There was a problem saving the payment.",false); } view.CloseView(); } }

Again, this is just another option you could choose,based on the requirements and architecture you already have in place. The nice thing about this solution is that the presenter and view do not need to change in order to handle new types of payments. All the work is done in the back end!!

Comments [5] | | # 
 Monday, October 09, 2006
Monday, October 09, 2006 7:09:07 PM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | C Sharp | ScreenCasts )

Well, it's been a long time coming, I am finally posting the second video in my applied test driven development for web applications series.

Although this is video number 3, it is really a fresh start that tries to start with less plumbing than was originally present when I started the first video. This was done on purpose. The video has now been revamped to show people how to start working with the Passive View flavour of Model View Presenter. The lack of infrastructure will also allow me the opportunity to show people how TDD will be applied to all layers of the application. At the end of this video you will have a (semi) working Customer management screen. Over the course of the next couple of weeks (I will be consistent this time), we will proceed to drive out the remaining functionality of both the screen itself and the underlying layers required.

You will note that I am still making use of the old Northwind database. If anyone has any ideas for a small application that requires the use of a database, I am all ears. I would much rather build something that may be used (other than for learning), as opposed to the fictitious example that focuses around the Northwind database. Again, feel free to fire your ideas at me, and I can easily change the future video to actually build out the app in mind.

You will have to excuse the coughing and sputtering in this video, as I am recovering from a nasty bout of Sinusitis (first ever encounter).

Feel free to give me feedback on this video as you see fit!!

**** If you want to run the build on your local machine, make sure you make any necessary changes to the local.properties.xml file, and ensure that the folder specified by the database path in your local.properties.xml file exists******

I will also point out, that I am going to try to release a video at least every 2 weeks. It could be more frequent based on feedback and demand!!

Resources

Comments [14] | | # 
 Sunday, October 08, 2006
Sunday, October 08, 2006 9:56:30 PM (Mountain Standard Time, UTC-07:00) ( Tools )

This took me a lot longer to figure out than it should have. I try to almost exclusively use the keyboard for a lot of my development tasks (and other tasks in windows). Obviously, when ReSharper came out (oh so long ago) I was thrilled that I could up my productivity in Visual Studio by taking advantage of the wealth of keyboard shortcuts that it offered. For the longest time, one thing bugged me about ReSharper (trust me, it is hard to find something that does with this product). I was sure that you had to use the mouse to close the Unit Test Runner dialog. The standard CTRL - SHIFT - F4, ReSharper shortcut, worked on all of the other ReSharper popup dialogs except the Unit Test Runner dialog. I tried ALT-F4, but that just closed down all of studio.

I emailed the Jetbrains guys and told them that it would be awesome to include a keyboard shortcut that allows you to close the Unit Test Runner dialog without using the mouse. At that time, they informed me that it was something they were going to be looking into.

Last Friday, I was coding up a storm and taking advantage of the Unit Test Runner, and I was annoyed that I had to reach for my mouse to close it. I started randomly hitting keys on the keyboard and then all of a sudden a thought popped into my head – “Hit Shift-Esc”. There is nothing in the ReSharper default keymap that suggests that this key sequence does anything. Sure enough, after I ran a test with the unit test runner dialog, Shift-Esc closed it down for me.

Again, I am not sure if this has been there the whole time, or if is a new shortcut that has been added to recent releases of the product. Whatever then answer, I am glad I finally found it!!!

Comments [3] | | # 
Sunday, October 08, 2006 4:00:00 PM (Mountain Standard Time, UTC-07:00) ( .Net 2.0 | Patterns )

I have had a couple of questions over the last couple of weeks as to which flavour of Model-View-Presenter I am partial to. In regards to the recent split of the pattern that Martin Fowler has established, I am a big proponent of the Passive View variant of the pattern. The Passive View approach allows me to push even more code down into the presenter, as it is now directly responsible for responding to events on the view. In the example that I have given in the past, I show how the view is responsible for invoking a method on the presenter whenever something needs to be done. In practice, I expose events on the interface for the view, that the view is responsible for raising. For example, when the a save button is clicked on the view, I can have the view raise a save event. The Save event is handled by an event handler on the presenter, which can then invoke the appropriate functionality within itself. This frees the view from needing to know which method to call on the presenter when something needs to be done.

With regards to the different flavours of MVP, they all have pros and cons. You will also find that many people were already using the Passive View approach, before it even received its own name!!

Comments [4] | | # 
 Saturday, October 07, 2006
Saturday, October 07, 2006 5:48:22 PM (Mountain Standard Time, UTC-07:00) ( Presentations )

For those of you who were hoping to catch up with me at next weeks Tulsa Tech Fest, I regret to announce that I will no longer be able to attend the conference. I contacted David Walker earlier in the day to let him know that I was not going to be able to make it.

I am hoping that there will be another opportunity in the future to come down to the states and deliver a presentation on any one of the topics that I feel extremely passionate about.

Comments [6] | | # 
 Friday, October 06, 2006
Friday, October 06, 2006 7:31:40 AM (Mountain Standard Time, UTC-07:00) ( )

One of my Canadian cohorts, James Kovacs, has just received a MVP - Visual Studio Solutions Architect. James has been speaking in and around Calgary (and surrounding cities) for quite some time. He is a very knowledgeable .Net guy, and an all around nice person!!

Congrats James, it has been a long time coming!!

Comments [0] | | # 
 Monday, October 02, 2006
Monday, October 02, 2006 4:00:12 PM (Mountain Standard Time, UTC-07:00) ( Presentations )

The family and I got back yesterday evening from Edmonton. We were up there both enjoying the attractions of the West Edmonton Mall, as well as me presenting and attending the first ever Edmonton Code Camp. It was great to see so many people turn up to attend sessions on a Saturday. I feel that if you want to truly excel and grow as a developer you sometimes need to be willing to sacrifice a small amount of personal time every now and then.

It was awesome to be joined by fellow Calgarians John Bristowe, James Kovacs, Daniel Carbajal, Terry Thibodeau, and Shary Mudassir.

I presented after James Kovacs, who gave an awesome presentation on tools for .Net developers. If you are an independent .Net developer and are looking to complement your developer toolkit, you need to rush over to James' blog, and download the tools that he recommends for developers. I ended up giving a presentation on advanced uses of Generics in .Net 2.0. The problems and solutions were coded up completely on the fly, which made for a pretty interesting presentation. I am glad that people's eyes were opened to the fact that there are a lot of things you can do with Generics aside from collections.

A pleasant surprise for me was witnessing the presentation dynamics of Justice Gray and Steven Rockarts. They opened up the day with a presentation on Ruby and .Net interop. They employed a technique that I have not seen used before in a presentation. They pre-recorded their coding sessions, so they could play them back at faster speeds, allowing them to focus on the meat of the content. If you have a user group and are interested in learning about Ruby and .Net interop, you need to get these guys down there.

An ex-coworker of mine ,Neil Bourgeois, gave an excellent talk on Refactoring. He accompanied it with an excellent example application that he utilized as the context of applying several refactorings to improve the quality and cohesiveness of the codebase.

Aside from some of the questionable people (not attendees) who showed up at the presentation, I had a blast at the ECC. Steven, Donald, and Justice (sorry if I'm forgetting any names) did a fantastic job of coordinating and executing this event.

I look forward to what they will have in store for next year.

Comments [4] | | #