CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeffrey Palermo (.com)

Blog moved to www.jeffreypalermo.com

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.

 

 



Comments

luca said:

Good post! Thx

# July 19, 2007 11:49 AM

Jeremy D. Miller -- The Shade Tree Developer said:

I&#39;m awful at returning emails. It was even one of my new year&#39;s resolutions to reply to emails

# July 22, 2007 5:57 PM

About Jeffrey Palermo

Jeffrey Palermo is a software management consultant and the CTO of Headspring Systems in Austin, TX. Jeffrey specializes in Agile coaching and helps companies double the productivity of software teams. Jeffrey is an MCSD.Net , Microsoft MVP, Certified Scrummaster, Austin .Net User Group leader, AgileAustin board member, INETA speaker, INETA Membership Mentor, Christian, husband, father, motorcyclist, Eagle Scout, U.S. Army Veteran, and Texas A&M University graduate. Check out Devlicio.us!

This Blog

Syndication

News

Headspring Systems

View Jeffrey Palermo's profile on LinkedIn

See my new blog at .jeffreypalermo.com