Friday, April 16, 2010

DevConnections VS 2010 Launch Event Sessions

This week I gave three talks at the Visual Studio Connections conference launch event for Visual Studio 2010. The topics included using Workflow 4 in service applications, writing custom activities in Workflow 4, and unit testing services and workflows.

You can download the slides and demos for each here:
VWF01: Workflow 4 Service Applications      Slides   Demos
VWF02: Workflow 4 Custom Activities         Slides   Demos
VWF03: Unit Testing Workflows and Services  Slides   Demos

It was great to see the interest and enthusiasm surrounding the launch of VS 2010. There is so much great new stuff there and in the .NET 4 framework to be excited about, as well as the launch of Silverlight 4.

I think one of the most important things for companies to keep in mind is that they can move to VS 2010 safely and keep building and supporting apps for .NET 3.5 and even back to 2.0 for as long as they need to for their deployment environments. But meanwhile they can start benefiting immediately from the big improvements in the VS 2010 IDE, including better code editing features, significantly improved designer for WPF and Silverlight, faster loading References window, IntelliTrace and so much more.





Friday, April 16, 2010 10:37:46 PM (GMT Standard Time, UTC+00:00)
Comments [15]  | 


  Friday, January 01, 2010

MVP – Connected Systems for another year

Always a nice way to start the new year, with the email telling me I have been awarded Microsoft MVP for another year. This makes 7 years running, a good streak that I hope to continue.

Being an MVP means a lot of things to a lot of different people. Things I love about the program are numerous:

  • Direct access to product team members that really seem to listen and respond based on the fact that you are an MVP
  • Opportunities to participate in early adopter events, SDRs, feedback sessions to help shape where Microsoft takes its developer products
  • Opportunities to teach and evangelize those products to the community
  • Recognition of expertise from customers based on the title
  • MSDN and TechNet subscriptions

This year I’ll be continuing to have a split focus between both connected systems (WCF and WF in particular) and client technologies (Silverlight and WPF). Lots of conferences, classes, user groups, code camps and things like that already planned or to be planned. Also a lot of writing this year (more on that in a subsequent post) and plan to get more MSDN webcasts going this year as well.

Its going to be an exciting year and an exciting decade. Bring on the technology!





Friday, January 01, 2010 3:37:43 PM (GMT Standard Time, UTC+00:00)
Comments [3]  | 


  Thursday, December 31, 2009

Read and Recommended: Confessions of a Public Speaker

I just finished reading Confessions of a Public Speaker by Scott Berkun, thanks to the recommendation from Stephen Forte. I’d highly recommend this book for anyone who gives talks at user groups, conferences, code camps or even just tech leads and developers who have to present to their team from time to time. Doesn’t matter if you are a deeply experienced speaker or someone just trying to expand your exposure and knowledge, this book is good for all who do any speaking to groups.

It is a quick and entertaining read, highly suitable for e-Book (I read the entire book over a dozen or so workouts on the elliptical machine at the gym using Kindle for iPhone), and offers great insights and enjoyable stories that will help anyone who has to talk to crowds small to large. Scott does a great job of capturing the experiences, challenges, and recommended techniques from a lot of public speaking.  It will help you get over fears, figure out ways to improve your presentation techniques and communication effectiveness, and generally just make preparing for and delivering a talk a much better and easier thing.





Thursday, December 31, 2009 2:31:42 PM (GMT Standard Time, UTC+00:00)
Comments [3]  | 


  Friday, December 18, 2009

Speaking at DevTeach Toronto March 8-12

I was selected to speak this year at DevTeach Toronto and will be giving two talks:

Leverage WCF RIA Services for a Quick N-Tier Silverlight Solution

Separate Your UI Concerns with MVVM & Prism

I’m really looking forward to it. DevTeach is a great little show densely packed with awesome speakers, so I count myself lucky to be included among them. It has been a couple of years since I have been able to speak there due to schedule conflicts with all of their shows, so I am happy the timing worked out this year to be able to go.





Friday, December 18, 2009 1:50:19 PM (GMT Standard Time, UTC+00:00)
Comments [1]  | 


  Tuesday, December 08, 2009

Detecting the Active View in a Prism App

A bit overdue, but a while back I wrote a post on handling graceful shutdown in a Prism application through the use of commands here and here. In those posts, I also promised to talk about detecting active views.

Baked into the Prism code since version 1 is an ability to detect when a view is active automatically as long the view is hosted in a region. It is a bit under-documented and hard to discover, but actually works quite nicely for a lot of scenarios.

Specifically in the example simple document editor I showed in the previous posts, I needed to detect when a given document was active so that I could enable or disable the global Save button in the toolbar based on the active document. That was based on state associated with the view in its ViewModel, a dirty flag indicating whether the document had been edited or not. In other contexts you might fire a pub-sub event indicating an active item, or you could change a bunch of formatting on the fly based on the active or inactive state of the view.

It actually takes very little code to get this done.

Part of the infrastructure code for Prism includes some things called region adapters. You mostly don’t have to even know they are there, but they provide the bridge between the abstract concept of a region and a specific type of container control in WPF or Silverlight. If the region that a view ends up in supports selection (specifically derives from Selector in WPF or Silverlight or is a custom container with its own region adapter that indicates selection), then when the view is selected (i.e. TabItem selected in a TabControl, ListBoxItem selected in a ListBox control, ListViewItem selected in a ListView), a behavior in the region is invoked that checks the view to see if it supports the IActiveAware interface.

IActiveAware

IActiveAware is a simple interface you can implement on your views to indicate that you want the view to be notified when it is made active or inactive. It looks like this:

public interface IActiveAware
{
    /// <summary>
    /// Gets or sets a value indicating whether the object is active.
    /// </summary>
    /// <value><see langword="true" /> if the object is active; otherwise <see langword="false" />.</value>
    bool IsActive { get; set; }

    /// <summary>
    /// Notifies that the value for <see cref="IsActive"/> property has changed.
    /// </summary>
    event EventHandler IsActiveChanged;
}

The IsActive flag lets you know if your view is active, and the IsActiveChanged event will fire when that state changes.

If you implement this on your view class (typically a user control), then you need to ensure the event gets fired when the state is changed by the region behavior. Since you shouldn’t put the actual logic code of what to do when that active state changes in the view definition itself, you will also want to get that state change transmitted into the view model. If you are following the typical pattern for ViewModel, your ViewModel will be set as the DataContext for the view. You can also implement IActiveAware on the ViewModel and have a nice decoupled way to dispatch the state change into the ViewModel without coupling the view to the ViewModel.

In the sample document editor, the view implementation of the interface looks like the following:

private bool _IsActive;
public bool IsActive
{
    get
    {
        return _IsActive;
    }
    set
    {
        _IsActive = value;
        IActiveAware vmAware = DataContext as IActiveAware;
        if (vmAware != null)
            vmAware.IsActive = value;

    }
}
public event EventHandler IsActiveChanged = delegate { };

 

The setter for the IsActive property will again be called by the region behavior, and in that setter, we take care of both firing the event on the view (since it fully implements IActiveAware) and also pass the setting call into the ViewModel if appropriate by checking to see if the object set as the ViewModel implements IActiveAware as well. If it does, we just set its IsActive property to the value being set on the view itself.

Notice the syntax for the IsActiveChanged event. We call this the “delegate trick”. By declaring an empty anonymous delegate for the event, you are basically subscribing for the life of the object a single, no-op subscriber to the list who cannot be removed. That means that not only can you blindly fire the event without checking for null, but it also solves a nasty little race condition if your null check gets called right before a thread interrupt and the last subscriber is removed before your thread resumes. The question always comes up of whether that will have a performance impact. The strict answer is yes. A couple extra instructions on the stack when you fire your event. A few nanoseconds lost on a modern machine. If that is truly the performance bottleneck in your program, contact me – I want to hire you, because you are the best programmer on the planet or I don’t want to hire you because you are not building anything real.

The ViewModel implementation of the IActiveAware interface is where the real work gets done, specifically setting the enabled state of the Save command.

public bool IsActive
{
    get
    {
        return _IsActive;
    }
    set
    {
        _IsActive = value;
        SaveCommand.IsActive = value;
        IsActiveChanged(this, EventArgs.Empty);
    }
}


public event EventHandler IsActiveChanged = delegate { };

 

So that’s it. Simple, effective. Implement IActiveAware on your view. Dispatch the setting of the IsActive property into your ViewModel by casting the DataContext to IActiveAware and implementing IActiveAware on your ViewModel. In your ViewModel, do whatever behavior is appropriate for your view.

Any comments or questions welcome.





Tuesday, December 08, 2009 3:03:52 AM (GMT Standard Time, UTC+00:00)
Comments [4]  | 


  Saturday, November 14, 2009

Slides and Demos from VS/Architect Connections This Week

I gave 4 sessions and repeat recorded a 5th this week at Visual Studio and Architect Connections in Las Vegas. The line up was as follows:

Build Workflow 4.0 Service Applications – covered the service messaging capabilities of workflow 4.0. Covered the Receive activity (and coupled SendReply) for exposing service operations from workflows, as well as Send/ReceiveReply (and the code generated activities) for calling services. Also covered the three forms of correlation: Request-Reply, Context (protocol), and Content correlation.

Slides    Demos

Wrap Your Head Around Concurrency in WF 4.0 – Covered all the many forms of concurrency in workflows. Where threads are doing what, how to use the parallel activities and the pseudo-concurrency that you get with that. Also showed how the built-in InvokeMethod executes asychronously, as well as how to build a custom async activity.

Slides   Demos

Connecting Smart Clients Through the .NET Service Bus – Covered basic use of .NET Service Bus to connect a client to back end services and the benefits of doing so. Also spent a good deal of time on event driven scenarios -  being able to push things to the client from back end services or for peer-to-peer communications from other clients. Discussed current and future state of affairs for document/data sharing and synchronization.

Slides   Demos

Build Testable Client and Service Applications – Covered practices and patterns for making applications more testable. Discussed benefits and principals of TDD, S.O.L.I.D., IoC, DI, Repository, Separated Presentation, and closed with a number of testability tricks for unit testing.

Slides   Demos





Saturday, November 14, 2009 6:56:11 PM (GMT Standard Time, UTC+00:00)
Comments [2]  | 


  Wednesday, November 04, 2009

Use Extension Methods to Phase Out a Bad API

I’m working on a project for a customer where we are trying to get a new version of a product out the door. We need to add some features to an existing API, but don’t want to break the existing API for existing customers. Common story, common place to be.

However, in adding these new features, we really need to be modifying an existing API to add new options to existing methods. But we find ourselves in a place I’ve seen a number of times: the API tried to be too granular about its arguments. It provided flexibility for optional arguments with overloaded methods. Not a bad thing from an OO perspective. The slippery slope is trying to anticipate how many arguments you might actually need to that method over time and which of those arguments might be optional.

Defining a Clean, Version Tolerant API

Say you start with a simple API like this:

public interface ISomeInterface
{
    void SomeMethod(double alwaysNeeded);
    void SomeMethod(double alwaysNeeded, int optionArg1);
    void SomeMethod(double alwaysNeeded, string optionArg2);
    void SomeMethod(double alwaysNeeded, int optionArg1, string optionArg2);
}

There is one always needed argument, and a couple of optional args. Fine when there are just two options. What about when the list grows to 3, 4, 5, 6? How many overloads do you have to add to cover all the reasonable combinations of those arguments a user might want? The size of your API goes exponential, and the usability of it goes downhill quick.

This is the situation we find ourselves in. And this is why I have long recommended that unless an API is going to be static and always take the same set of arguments, you are better off packaging up those arguments in a single complex argument – a data structure single argument such as the following:

public class MyMethodArg
{
    public double AlwaysNeeded { get; set; }
    public int OptionalArg1 { get; set; }
    public string OptionalArg2 { get; set; }
}

Then you can simplify the interface definition to just the following:

public interface ISomeInterface
{
    void SomeMethod(MyMethodArg arg);
}

Now, over time, you can add additional required or optional arguments without affecting the interface API at all. As long as you write graceful handling for when optional parameters are not set explicitly on the data structure, you have much better ability to change the underlying arguments over time without breaking existing clients. And you have a much cleaner, easier to understand API.

Extension Methods to the Rescue

So then the question becomes: If you find yourself with an API that looks like the original version and you want to move to the cleaner version immediately above, do you have to break all your existing clients to get there? Thanks to extension methods, the answer is no.

Say you have existing clients that have code that depends on the original API. A simple one might look like the following console app:

class Program
{
    static void Main(string[] args)
    {
        ISomeInterface itf = new SomeImplementation();
        // V1 methods - obsolete
        itf.SomeMethod(1.0);
        itf.SomeMethod(1.0,42);
        itf.SomeMethod(1.0,"foo");
        itf.SomeMethod(1.0, 42,"foo");
        // V2 method
        itf.SomeMethod(new MyMethodArg { OptionalArg1 = 42 });
        Console.WriteLine("Press Enter to Exit...");
        Console.ReadLine();
    }
}

For sample purposes, say the original implementation looked like the following:

public class SomeImplementation : ISomeInterface
{
    void ISomeInterface.SomeMethod(double alwaysNeeded)
    {
        Debug.WriteLine("SomeMethod no optional args");
    }

    void ISomeInterface.SomeMethod(double alwaysNeeded, int arg)
    {
        Debug.WriteLine("SomeMethod optional int arg");
    }

    void ISomeInterface.SomeMethod(double alwaysNeeded, string arg)
    {
        Debug.WriteLine("SomeMethod optional string arg");
    }

    void ISomeInterface.SomeMethod(double alwaysNeeded, int arg1, string arg2)
    {
        Debug.WriteLine("SomeMethod optional int and string args");
    }
}

What you can do is use Extension methods to move the old API off the primary interface you want to keep for the long term (assuming there are also other methods and properties on that interface that you want to remain there instead of just defining a new interface with the new API). You could add the following class to your existing project:

public static class SomeInterfaceExtensions
{
    [Obsolete]
    public static void SomeMethod(this ISomeInterface itf, double alwaysNeeded)
    {
        itf.SomeMethod(new MyMethodArg { AlwaysNeeded = alwaysNeeded });
    }

    [Obsolete]
    public static void SomeMethod(this ISomeInterface itf, double alwaysNeeded, int arg)
    {
        itf.SomeMethod(new MyMethodArg { AlwaysNeeded = alwaysNeeded, OptionalArg1 = arg });
    }

    [Obsolete]
    public static void SomeMethod(this ISomeInterface itf, double alwaysNeeded, string arg)
    {
        itf.SomeMethod(new MyMethodArg { AlwaysNeeded = alwaysNeeded, OptionalArg2 = arg });
    }

    [Obsolete]
    public static void SomeMethod(this ISomeInterface itf, double alwaysNeeded, int arg1, string arg2)
    {
        itf.SomeMethod(new MyMethodArg { AlwaysNeeded = alwaysNeeded, OptionalArg1 = arg1, 
                                                                    OptionalArg2 = arg2 });
    }
}

Then, the implementation class can be collapsed to the following:

public class SomeImplementation : ISomeInterface
{
    void ISomeInterface.SomeMethod(MyMethodArg arg)
    {
        Debug.WriteLine("SomeMethod complex arg");
    }
}

The client can remained unchanged against the V1 API thanks to the extension methods, but will now get compiler warnings that the API is obsolete thanks to the Obsolete attributes. But they won’t break. New clients will not even see the old API unless they go looking for it, and then they should be smart enough not to write new code against things marked with the Obsolete attribute when there is a perfectly usable method on the primary API itself.

So this is the approach we are going to use to move forward the original lack-of-forethought API and clean it up for the long term.

Obviously this approach will only work if your clients (that you don’t want to break) are on .NET 3.5. If you could afford to lock them down to just .NET 4.0 or later, you would have another option with C# optional parameters or default values, but that is unlikely for most apps at this point in time.





Wednesday, November 04, 2009 8:51:30 PM (GMT Standard Time, UTC+00:00)
Comments [1]  | 


  Wednesday, October 28, 2009

Sydney .NET User Group Fit Walk

Last week I had the privilege of speaking at the Sydney .NET User’s Group while in Sydney teaching a WCF Master Class. It was an outstanding group and I spoke on WF 4 and Prism (Composite Application Guidance for WPF and Sliverlight). Had some great questions and discussion with the attendees, which is always what makes a group stand out in my mind.

If you want the slides and demos for the talks, you can find them here:

First Look at WF 4:   Slides   (no pre-built demo code, all on the fly demos in VS 2010 Beta 2)

Building Composite WPF and Silverlight Applications:   Slides    Demos

The other thing that made this group stand out for me (besides the above and the fact that it is run by friend and fellow RD Adam Cogan from SSW Software) was that instead of going out for beers or something else unhealthy afterwards, a small group of us went for a short power walk for some exercise afterwards around the area of the user group meeting. You can see the route we walked here:

http://www.mapmyride.com/route/australia/earlwood/465125612609191527

Nice variation for someone who is trying to lose weight and good chance to keep the technology discussion going with some of the attendees afterwards. Thanks to Adam for organizing!





Wednesday, October 28, 2009 4:41:32 PM (GMT Standard Time, UTC+00:00)
Comments [1]  | 

















January, 2012 (1)
November, 2011 (4)
October, 2011 (1)
September, 2011 (2)
August, 2011 (1)
July, 2011 (1)
May, 2011 (5)
March, 2011 (4)
February, 2011 (2)
January, 2011 (3)
November, 2010 (4)
October, 2010 (1)
September, 2010 (5)
August, 2010 (5)
July, 2010 (6)
June, 2010 (8)
May, 2010 (2)
April, 2010 (2)
January, 2010 (1)
December, 2009 (3)
November, 2009 (2)
October, 2009 (3)
September, 2009 (3)
August, 2009 (2)
July, 2009 (3)
May, 2009 (3)
April, 2009 (2)
March, 2009 (1)
February, 2009 (2)
January, 2009 (2)
December, 2008 (1)
November, 2008 (2)
October, 2008 (5)
September, 2008 (4)
August, 2008 (2)
July, 2008 (1)
June, 2008 (2)
May, 2008 (2)
April, 2008 (3)
February, 2008 (6)
January, 2008 (3)
December, 2007 (1)
November, 2007 (1)
October, 2007 (5)
September, 2007 (1)
July, 2007 (3)
June, 2007 (8)
April, 2007 (2)
March, 2007 (4)
February, 2007 (1)
December, 2006 (2)
November, 2006 (9)
October, 2006 (5)
September, 2006 (3)
August, 2006 (2)
July, 2006 (4)
June, 2006 (5)
May, 2006 (10)
April, 2006 (4)
March, 2006 (2)
February, 2006 (12)
January, 2006 (7)
December, 2005 (2)
November, 2005 (15)
October, 2005 (6)
September, 2005 (7)
August, 2005 (3)
July, 2005 (10)
June, 2005 (11)
May, 2005 (7)
April, 2005 (8)
March, 2005 (6)
February, 2005 (2)
January, 2005 (6)
December, 2004 (3)
November, 2004 (5)
October, 2004 (2)
September, 2004 (5)
August, 2004 (13)
July, 2004 (6)
June, 2004 (14)
May, 2004 (17)
April, 2004 (12)
March, 2004 (8)
February, 2004 (10)
January, 2004 (14)
December, 2003 (9)
November, 2003 (13)
October, 2003 (3)





Sign In
Copyright © 2006-2007 Brian Noyes. All rights reserved.

designed by NUKEATION STUDIOS