Streamline Model-View-Presenter with new StructureMap feature – level 300

I'm going to present you with a very exciting new feature of StructureMap that is available in the 2.0 release.  You can download StructureMap from SourceForge.

There are plenty of articles about StructureMap's service location capabilities, and the documentation is quite good, but I'll throw out the bread-and-butter usage scenario for service location.  Here is is.

I have an ICustomerRepository, and an "impl" class that implements the interface, CustomerRepository.  As the names suggest, this interface will return an array of Customer(s) given a whole or partial phone number.  Here is the full code.

    1 using StructureMap;

    2 

    3 [PluginFamily("Default")]

    4 public interface ICustomerRepository

    5 {

    6     Customer[] GetCustomersByPartialPhoneNumber(string phoneNumberOrPartial);

    7 }

    8 

    9 [Pluggable("Default")]

   10 public class CustomerRepository : ICustomerRepository

   11 {

   12     public Customer[] GetCustomersByPartialPhoneNumber(string phoneNumberOrPartial)

   13     {

   14         //do the right thing to find the customers;

   15         return null;

   16     }

   17 }

   18 

   19 public class Customer

   20 {

   21     private string _name;

   22     private string _phoneNumber;

   23 

   24     public Customer(string name, string phoneNumber)

   25     {

   26         _name = name;

   27         _phoneNumber = phoneNumber;

   28     }

   29 

   30     public string Name

   31     {

   32         get { return _name; }

   33         set { _name = value; }

   34     }

   35 

   36     public string PhoneNumber

   37     {

   38         get { return _phoneNumber; }

   39         set { _phoneNumber = value; }

   40     }

   41 }

In another place, I want to make use of the ICustomerRepository interface, so all I need are the following lines:

   49 //imagine this method were real.

   50 ICustomerRepository repository = ObjectFactory.GetInstance<ICustomerRepository>();

   51 Customer[] customers = repository.GetCustomersByPartialPhoneNumber("555-5555");

   52 return customers;

Of course, when my application starts, I'll put these lines to ensure it will work (or I could use a StructureMap.config file).

   47 StructureMapConfiguration.UseDefaultStructureMapConfigFile = false;

   48 StructureMapConfiguration.ScanAssemblies().IncludeTheCallingAssembly();

Now that you get the gist of it, I'm going to use StructureMap to enable the Model-View-Presenter pattern in a cleaner way with ASP.NET UserControls.  First consider the following usage:

I have a page that has a complicated piece which has been delegated to a usercontrol-presenter pair.  The page, of course, will embed this usercontrol in the appropriate place.  Immediately you can spot the problem:  The "Foo" view is responsible for creating the "Widget" view.  Then the Widget view creates its presenter and uses it.  This is too much responsibility for both views. 

Now consider an alternative:
 

Now notice that the FooPresenter is responsible for creating and using WidgetPresenter.  WidgetPresenter, in return, uses StructureMap to service-locate its view, which implements IWidgetView.  Because Widget.ascx.cs implements IWidgetView, this wiring works easily.  The StructureMap change that made this possible is the following usage of the configuration.  Here is the code:

   58 public interface IWidgetView

   59 {

   60     void ShowWidget(RedWidget theRedWidget);

   61 }

   62 

   63 public class RedWidget

   64 {

   65 }

 And the usercontrol that is the view:

    5 public partial class Widget : UserControl, IWidgetView

    6 {

    7     protected void Page_Load(object sender, EventArgs e)

    8     {

    9     }

   10 

   11     public void ShowWidget(RedWidget theRedWidget)

   12     {

   13         HttpContext.Current.Response.Write("Red widget shown");

   14     }

   15 }

 And the configuration that makes this possible:

   66     void Application_Start(object sender, EventArgs e)

   67     {

   68         StructureMapConfiguration.UseDefaultStructureMapConfigFile = false;

   69         StructureMapConfiguration.ScanAssemblies().IncludeTheCallingAssembly();

   70         StructureMapConfiguration.BuildInstancesOf<IWidgetView>().TheDefaultIs(

                        Registry.LoadUserControlFrom<IWidgetView>("Widget.ascx"));

   71     }

 Now that we can service-locate asp.net usercontrols, we can inject them as well.  The next step is having the WidgetPresenter receive IWidgetView in the constructor.  StructureMap will chain-create the usercontrol in order to create WidgetPresenter.  Now, our presenter is in control, and the views can concentrate on presenting information to the user and not worry about control flow.

 

 

Web service versioning for dummies – level 200

This post is aimed at providing a good way to version web services.  Note that there are many ways to do this, and this is just one way.

When versioning a service, it’s important to be able to run multiple versions side by side.  When you upgrade the web service for one client, you can’t immediately take away the current version from existing clients.  Existing clients will move to the new version if/when they can/want to.

The identifier for the web service is the Url, so the version number must be embedded in the url.

Here is one way to do it:
https://theServer/v1_0/theService.asmx
When you want to modify the web service, do so, but deploy it side-by-side with the current version:
https://theServer/v1_5/theService.asmx

With this versioning strategy, you will be able to publish upgraded web services while maintaining service to existing customers.  Down the road, when you have confirmed that all customers of the v1.0 service have moved to the v1.5 service, you can discontinue the v1.0 version.

I’ve learned that if there are urls with dots (.) in the path, then the IIS lockdown tool won’t work with them.  For that reason, it’s probably good to use (_) instead of (.) for the version delimiter.  I also agree with the first commenter that major and minor versions are enough.

There are plenty of folks talking about web service versioning:
http://www-128.ibm.com/developerworks/webservices/library/ws-version/
http://www.webservicesarchitect.com/content/articles/irani04.asp

SOA has not lived up to it’s hype – level 200

A quick google search will reveal a raging debate on the merits of SOA.  It has cooled down a bit from 2005 where every time I turned around, there was another session at Tech Ed on SOA.  The talk about SOA has just started if its landscape is going to be anything like the adoption landscape for OOP.  SOA has not lived up to it’s hype yet, but to be fair, we have to give it another two decades. 

We don’t think about it much, but object-oriented programming began in the 1960’s with the Simula language.  Smalltalk helped the movement, but C++ brought object-oriented development into the mainstream in the late ’80s when the ANSI group was formed.  From 1962 to 1989, OO was a lot of talk and theory with handfuls of folks implementing real systems using the concepts.  When C++ hit, many more programmers came on board.  Java furthered the adoption of object-oriented concepts, and .Net seems to have pulled the remaining part of the programming market into OO.  When I think about how long it has taken for the average programmer to ackowledge OOP, I wonder if it will take that long for other paradigm shifts.

It remains to be seen if SOA really has the merits granted it by all the marketing hype or if it is just a new name for integration.  We won’t really know for at least another decade, I imagine.  Folks have been integrating systems when necessary for years, so it remains to be seen if this new (everything is exposed as a service) strategy works.

I like the way Jeremy Miller puts it:  “The ‘if you build it, they will come’ approach doesn’t work.”  I agree.  As with any part in programming, building something with the wish that someone will use it someday doesn’t work.  If you are adding a service endpoint to a system out of necessity because someone else need to integrate NOW, then the business value is there, and it’s the same kind of integration that has been going on for years.  Some large companies need to integration now, and we see case studies galor: google search.

What we won’t find out until many moons from now is if these SOAs worked.  Every project is declared a success immediately after completion, so we can’t count on reported results right now.  The true test is if these integrated enterprises are maintainable and cost-effective.  Architects from big companies are saying “yes they are” right now, but no one thinks their child is ugly.