Removing Repetitive Boiler Maker Code From View Models

November 17, 2010

While I was writing the BBQ Shack, I noticed that view model code calling into the business layer was repetitive across view models. The pattern I used was simple and widely accepted; background worker to make the asynchronous calls to the business layer.

The below code snippet was typical.  Background worker, exception checking, call to business layer, successful result code path, and exception result code path.

Old Pattern

void BackgroundWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) {
    e.Result = _iBLLItemCategory.Select(Convert.ToInt32(e.Argument));
}


void BackgroundWorker_RunWorkerCompleted(object sender, 
    System.ComponentModel.RunWorkerCompletedEventArgs e) {
    if (e.Error == null) {
        if (e.Result != null) {
            this.ic_ItemCategory = (ic_ItemCategory)e.Result;

        } else {
            _iViewModelUIService.MessageDialog("Data Error", 
                "Record Not Found",     
                string.Format("Item Category key: {0} not found", _objLoadKey.ToString));
        }

    } else {
        _objIViewModelUIService.ExceptionDialog(e.Error);
    }
}

I kept thinking about this, always looking for a better pattern.  I also wanted a pattern that only required a single line of code and still gave me all of the same benefits of the above code.

New Pattern

All of the above code condenses nicely down to one line of code that provides all of the above “old pattern” features.

The below repository method signatures describe the pattern.  The pattern for the method signatures is zero or more parameters, followed by the same last two; Action<T> resultCallback and Action<Exception> errorCallback.

public interface IItemRepository {

    void GetAll(Action<IEnumerable<Item>> resultCallback, Action<Exception> errorCallback);

    void Get(Int32 itemId, Action<Item> resultCallback, Action<Exception> errorCallback);

    Item Create();
}

The successful result of the method call is always calls the resultCallback delegate.

The unsuccessful result of the method call is always calls the errorCallback delegate.

This pattern is incredibly simple and leads to much cleaner code in the view model.  The errorCallback is a method in the view model base class.  This method can use a variety of techniques for displaying the error message to the user.

void LoadItems() {
    _itemRepository.GetAll(result => { this.DataItems.Source = result; }, this.DisplayException);
}

Repository Implementation – Bring on the Task Parallel Library (TPL)

The below implementation leverages the TPL Futures pattern.  Use of the TPL is optional, I’m using it here in this WPF application.  The TPL is not available in Silverlight 4 applications yet.  For Silverlight applications, change the implementation to use the common Silverlight asynchronous pattern.

The “pattern” is described in the above IItemRepository interface.  Like all interface contracts, implementation specifics can be platform specific and up to the developer.

Strongly recommend you read this book on MSDN: Parallel Programming with Microsoft .NET.  The book can also be purchased from Amazon here.  There is a book and Kindle version available.

[Export(typeof(IItemRepository))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ItemRepository : IItemRepository {

    readonly ThePhoneCompanyEntities _dataService;

    [ImportingConstructor]
    public ItemRepository(DataServiceFacade dataServiceFacade) {
        _dataService = dataServiceFacade.DataService;
    }

    void IItemRepository.GetAll(Action<IEnumerable<Item>> resultCallback,
        Action<Exception> errorCallback) {

        // This code can be refactored into a generic method
        // I left it this way to help with the learning process 
        Task<RepositoryResult<IEnumerable<Item>>> task =
            Task.Factory.StartNew(() => {
                try {
                    return new RepositoryResult<IEnumerable<Item>>(
                                _dataService.Items.ToList(), null);
                } catch(Exception ex) {
                    return new RepositoryResult<IEnumerable<Item>>(null, ex);
                }
            });

        task.ContinueWith(r => {
            if(r.Result.Error != null) {
                errorCallback(r.Result.Error);
            } else {
                resultCallback(r.Result.Package);
            }
        }, CancellationToken.None, TaskContinuationOptions.None,
            TaskScheduler.FromCurrentSynchronizationContext());
    }

    void IItemRepository.Get(Int32 itemId, Action<Item> resultCallback, 
        Action<Exception> errorCallback) {

        if(itemId != 0) {

            // This code can be refactored into a generic method
            // I left it this way to help with the learning process 
            Task<RepositoryResult<Item>> task =
                Task.Factory.StartNew(() => {
                    try {
                        return new RepositoryResult<Item>(
                            _dataService.Items.Where(
                                i => i.ItemID == itemId).FirstOrDefault(), null);
                    } catch(Exception ex) {
                        return new RepositoryResult<Item>(null, ex);
                    }
                });

            task.ContinueWith(r => {
                if(r.Result.Error != null) {
                    errorCallback(r.Result.Error);
                } else {
                    resultCallback(r.Result.Package);
                }
            }, CancellationToken.None, TaskContinuationOptions.None,
                TaskScheduler.FromCurrentSynchronizationContext());
        } else {
            resultCallback(((IItemRepository)this).Create());
        }
    }

    // I always create my entity objects in the business layer and never in the presentation layer
    Item IItemRepository.Create() {
        return new Item();
    }
}

Key Points

  • Call that does the actual work is wrapped in a try catch block.
  • The result of the asynchronous operation is wrapped in a RepositoryResult object.
  • The RepositoryResult is used to drive invoking the resultCallback or the errorCallback on the calling thread. The TaskScheduler.FromCurrentSynchronizatikonContext method call in the task.ContinueWith ensures the two callbacks are invoked on the calling thread. 

Download

This code is from one of my presentations at the patterns & practices 2010 Symposium. 

The article and video is here: http://blogs.msdn.com/b/kashiffl/archive/2010/10/21/patterns-and-practices-2010-symposium-content.aspx

This code can be downloaded from the article.

Close

I hope that this short post encourages you to look for possible refactorings in your own code and to take a look at the TPL. 

Have a great day,

Just a grain of sand on the worlds beaches.


Needed: Your Vote for 501K

November 16, 2010

In my previous blog post, Controlled Chaos, I told the story of my weekend’s activities and the startup 501K.

I also mentioned that our team was selected by independent judges as a winner for the Seattle Startup Weekend.

As a result, Team 501K has been entered into an international contest; winners are chosen by the public.

We Need Your Vote

Below are the important links:

Voting takes about 30 seconds total.  To prevent fraud, when you click the next button, you will enter your phone number, the computer will call your number immediately and provide you with a pin.  Enter the pin in the text box and you’re done.

Voting is only open for 2 days, so please vote today.

Votefor501K

Thank you for your vote and have a great day,

Just a grain of sand on the worlds beaches.

 


Controlled Chaos – The 501K Story

November 15, 2010

Updated 11/15/2010 – add link to video presentation.

Over 12-14 November 2010, Don Smith and I participated in the Seattle Startup Weekend with over 100 other developers, designers, entrepreneurs, and business managers. Some attendees came with the intention of getting help with their startup that is in-flight, others came with ideas that need watering and the soiled tilled; Don and I came to have fun and to contribute to the community in any way we could.

During the orientation meeting on Friday night, 12 Nov 2010, 35 of the 100 attendees presented ideas for a startup. I interviewed several of the startup idea presenters and chose the 501K startup idea presented by Eric Koester (http://www.greentrepreneur.org/).

At the end of the interview process, 15 teams (startup companies) were formed; the stage was now set for what was about to happen (keep reading…).

Saturday and Sunday were devoted to fleshing out the business scope, business model, design and program the business product.

Finally, on Sunday evening, each team would give a corporate presentation to four independent judges; presentations needed to included marketing materials, business plan and product demonstration. Judges would critique the team’s business plan, presentation, and product; feedback was designed to point the team down the path of success.

501K

501KHome 501KDonate

501K provides online services making it easy to set up and execute reoccurring donations. Visitors are presented opportunities that target causes in their community as well outside their community. Additionally, it allows members (membership is free) to set up their own causes that others can contribute to. Causes are one or more charities clustered together.

movie1 View presentation video here.

Over Saturday and Sunday our team:

  • scoped our business objectives
  • developed a business plan
  • iterated on product design and requirements
  • designed marketing materials
  • created a corporate presentation
  • designed the web site
  • created the web site art work
  • created all of the web pages
  • programmed authentication integration with Facebook (more providers to follow)
  • programmed recurring drafts using Amazon services (more payment providers to follow)
  • wrote the code for the ASP.NET MCV3 web site
  • created a SQL Server 2008 database with an abstracted repository layer for easy data access and testing
  • gave a corporate presentation that included a live demonstration with all of the above, including live interaction with both Facebook and Amazon.com (no demo-ware or smoke and mirrors)

Team 501K

Most team members had never met or only knew one other person before this weekend.

Meet our diverse team:

  • 5 – business folks (lawyer, consultant, company owner, and university students)
  • 1 – designer
  • 2 – Non-.NET programmers with Mac’s, no Visual Studio 2010
  • 3 – .NET developers with Visual Studio 2010

I’m astonished how folks from diverse backgrounds and skillsets came together, gelled as a working unit, put the project ahead of their personal goals for the weekend, and delivered what we did; on time and one budget (free).

Tell Me the Truth – What Really Happened – How was the Sausage Made?

What transpired over this weekend can best be described as high octane controlled chaos. Think about the pot we dove into. Only two days to actually start from scratch and deliver all of the above.

To pull this off, each group in our team had to work autonomously, yet in parallel. We had sync up meetings during both days; sometimes a meeting could result in one or more groups being reset, requiring adjustments to their time constrained deliverable.

From the designer & developer side of the house we had to stay flexible to survive the ever changing requirements. Trust me, Gumby has nothing on us. With only two days to deliver, we had to start working without assets developers and designers normally expect from business.

Think I’m pulling your chain; check out our beautiful running web site until late Sunday morning.

Team chemistry and trust is everything. Without this, the stress can easily derail a project. Focusing on the steak and not the peas, made this team very successful, and established a highly energized and creative atmosphere where each team member could deliver at their maximum potential.

Our designer, Facebook developer and Amazon developer worked on their Mac laptops. As progress was made the work was integrated into the ASP.NET MVC3 project.

Our .NET developers worked on the ASP.NET MVC3 web site, abstraction layer for data access and the database. (See below section on LINQ to SQL).

It wasn’t until after the Saturday 7:00pm team meeting that we had a concrete picture of the deliverable from a requirements, product workflow and 3rd party product integration perspective.

We continued to work until 1:00am Sunday. At this point, each piece of the puzzle was working autonomously; integration into the final product would start on Sunday after 9:00am.

Sunday was all about integration of each team members assets into the product and presentation. Business made a few additional product adjustments and the team collaborated on wordsmithing the deliverables.

Measurable Result

This was a bottom to top team effort. Each of the eleven members provided critical feedback and assets that lead to the overwhelming success of this work.

Our team was chosen as winners by the judges’ panel and we have been entered to compete at the national level.

Startup Weekend Food – Deluxe Geek Food

Only the finest for our geeks!

GeekFood

LINQ to SQL

Over the weekend, several Twitter Peeps asked me why the team elected to use LINQ to SQL for our demonstration product over the weekend.

LINQ to SQL has outstanding code first capabilities and features that are much simpler to implement than Entity Framework.

Remember, to set the team up for success, developers had to be incredibly flexible. We had to be able to adapt to change, delete the database, recreate it and then populate it with data. This change had to be accomplished in minutes. We had to have a process in place that allowed for a change at any time, including right up to game time that would not negatively impact the deliverable.

You must also consider that the data entities needed to play nice with ASP.NET MVC3. We wanted to be able to take advantage of some of the features that require entities to expose metadata in the form of attributes.

I did look at both solutions, neither of which I had ever used; in the end LINQ to SQL made the most sense for this weekend. When we move to production, we will move to low level ADO.NET for all data access.

Video

movie1 View presentation video here.

Close

I encourage you to attend at least one of these Startup Weekends in your area; it will be a growing and very fun experience. To locate an event in your area visit: http://startupweekend.org/cities/.

Have a great day,

Just a grain of sand on the worlds beaches.


Prism 4.0 For Visual Studio 2010, .NET Framework 4.0, WPF & Silverlight 4

November 12, 2010

 pnp_logo

The Microsoft patterns & practices team is excited to announce the release of:

Prism 4

For Visual Studio 2010, .NET Framework 4.0, WPF & Silverlight 4

Prism provides guidance designed to help you more easily design and build rich, flexible, and easy to maintain Windows Presentation Foundation (WPF) desktop applications, Silverlight Rich Internet Applications (RIAs) and Windows Phone 7 applications. Using design patterns that embody important architectural design principles, such as separation of concerns and loose coupling, Prism helps you to design and build applications using loosely coupled components that can evolve independently but which can be easily and seamlessly integrated into the overall application. Such applications are known as often referred to as composite applications.

Links

Audience

Prism is intended for software developers building WPF or Silverlight applications that typically feature multiple screens, rich user interaction and data visualization, and that embody significant presentation and business logic. These applications typically interact with a number of back-end systems and services and, using a layered architecture, may be physically deployed across multiple tiers. It is expected that the application will evolve significantly over its lifetime in response to new requirements and business opportunities. In short, these applications are “built to last” and “built for change.” Applications that do not demand these characteristics may not benefit from using Prism.

Key Benefits

  • Provides guidance and a re-usable library to help you develop flexible, easy to maintain WPF and Silverlight composite applications
  • Helps you to understand, implement and use key design patterns, such as MVVM and Dependency Injection
  • Supports the development of modular applications, allowing parts of your application to be fully developed and tested by separate teams
  • Helps you re-use application code and components across WPF and Silverlight, allowing you to create multi-targeted client experiences
  • Allows you to build a designer-friendly, dynamically composed user interface for your application
  • Includes reference implementations, quick-starts, hands-on-labs, as well as a comprehensive developers guide to get you up to speed quickly
  • Includes full source code to support code re-use or customization or for reference and education

In this Release

  • Prism Library for WPF, Silverlight and Windows Phone 7
    • Signed binary assemblies
    • Full source code
  • Example Applications and Hands-on-Lab Source Code
    • Reference Implementations (2)
    • QuickStarts (12)
    • Hands on Labs (2)
  • Documentation
    • Comprehensive developers guide showing how to use Prism within your application
    • A printable PDF of the developers guide – available on CodePlex

About patterns & practices

The Microsoft patterns & practices team provides a wide range of guidance to help customers save time and reduce risk on their software development projects by incorporating proven patterns and practices.  This applied engineering guidance includes both production quality source code and in-depth documentation.

The guidance is designed to help software development teams:

  • Make critical design and technology selection decisions by highlighting the appropriate solution architectures, technologies, and Microsoft products for common scenarios
  • Understand the most important concepts needed for success by explaining the relevant patterns and prescribing the important practices
  • Get started with a proven code base by providing thoroughly tested software and source code that embodies the recommendations

For more information: http://msdn.microsoft.com/practices


In the Box – MVVM Training

November 7, 2010

Updated 12 Nov 2010

InTheBox

What is In the Box?

In the Box is a high quality, multi-media training that is consumed within Visual Studio 2010.  Content is navigated and delivered using a next generation computer based training (CBT) experience, the Visual Studio 2010 Feature Extension.

In the Box, is a brand name for a series of CBT Feature Extensions I’ll release that are listed in the Visual Studio 2010 Add New Project dialog; see below image.  This release is MVVM Training, the next will be Prism Training.

In the Box features:

  • Visual Studio 2010 Feature Extension
  • Content delivered as text, code, images, diagrams, video, or hyperlinks to the Internet
  • Hierarchical navigation tool window for content navigation
  • Content is viewed inside Visual Studio 2010 tool windows
  • No additional downloads or dependencies; all content is in the box.  (except online videos)
  • Installed and updated from the Visual Studio Gallery
  • Managed (disabled or uninstalled) using Visual Studio Extensions Manager (see bottom of this page)
  • Authored using Microsoft Word and the Instant Feature Builder

What is in this release of In the Box?

Please watch this video as it will answer most of your questions.

This installment of In the Box contains in-depth MVVM Training that includes an eleven assembly example solution with projects targeting developers at different levels of experience

Who is the target audience?

  • If you have never used MVVM before, this training is for you. 
  • If you have been using MVVM for a while and want to learn more, this training is for you. 
  • If you are an expert, you will enjoy the MVVM Technical Description and MVVM Scenarios content.

What are the requirements to install In the Box?

Visual Studio 2010 Professional, Premium, or Ultimate.

Expression Blend 4 WPF SDK – Free download (see below comment on SDK) (Note: this is installed with Blend also)

For those developers using Visual Studio 2010 Express or Visual Studio 2008, you can use the links in the below download section to download a .mht version of the content along with the sample solution source.  The .mht file can be viewed in your browser by double clicking the file in Windows Explorer.

Please note: I have not tested this solution with the Express version.

Windows XP and Windows Server 2003 Users

In order to run Feature Builder on either XP or Server 2003 you must create an environment variable named LocalAppData (set by default on Windows Vista and Windows 7).

How to Add LOCALAPPDATA variable in Windows XP:

  • Right-click on the My Computer icon and choose Properties
  • Click Advanced
  • Click Environment Variables
  • Under User variables section, click New
  • In the Variable name: field, type LOCALAPPDATA
  • In the Variable value: field, type %USERPROFILE%\Local Settings\Application Data

How do I install In the Box?

Click on this Visual Studio Gallery Link and install from there.

After I install it, how do I get started?

Open Visual Studio 2010; File, New Project, Visual C#, In the Box, MVVMTraining.

NewProject

Videos

In the Box – MVVM Training Introduction video

You can view the above video using the web browser plug in, or you can download and watch an HD version of the video.  To download the HD version of the video, locate the, “About this video” section (lower right side of web page) and join Vimeo; it’s free and very quick to join.

Vimeo

Downloads

In the Box – MVVM Training on the Visual Studio Gallery

Visual Studio Express and Visual Studio 2008 Developers download the written content and sample application from my:

SkyDrive click here to download.

Note the link is to a folder; you will want to download both .zip files in the folder.

Expression Blend 4 SDK Requirement

I received a report from a developer having a problem with two references to the Expression Blend 4 SDK in two of the included projects.

I thought for awhile about including just these two DLL’s, but thought that would be a disservice, only providing two DLL’s.  I have opted to add the Expression Blend 4 SDK as a requirement because a high percentage of developers already have the SDK installed by Blend or by downloading it.

Have a great day,

Just a grain of sand on the worlds beaches.


Follow

Get every new post delivered to your Inbox.

Join 241 other followers