Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Dependency Injection and MVP in WebForms – It’s that Injection of the Presenter into the View that Stinks

Scott has a good essay on Dependency Injection. I have become a huge fan of dependency injection during my stay here at CodeBetter and appreciate its value not only from a testing point-of-view but also for helping reveal the intent and dependencies of a class. I use it all the time and have experienced Windsor, StructureMap, and ObjectBuilder.


In the real-world, however, it can be a bitch because inevitably you don’t have as much control as you would like.


Take the example of Webforms and using the Model-View-Presenter Pattern. By the very nature of Webforms, the view gets created for you but has a dependency on a Presenter Class. 99.9% of the examples I have seen on the Internet about getting access to the Presenter Class from within the View are something as follows where you are doing all the manual wiring:


 

public partial class AddCustomer : Page, IAddCustomer
{
private AddCustomerPresenter _presenter;

protected Page_PreInit(object sender, EventArgs e)
{
// Constructor Injection of Data Access Service and View
ICustomerDAO dao = Container.Resolve<ICustomerDAO>():
_presenter
= new AddCustomerPresenter(dao, this);

// Property Injection of Logging
ILoggingService logger = Container.Resolve<ILoggingService>():
_presenter.Logger
= logger;
}

//
}


 


Or, the presenter has a default constructor and wires up its needs itself, which is more about Service Location than Dependency Injection.


Either way, this still stinks in my humble opinion as I don’t want to have to manually inject the Presenter Class dependency into the view.


I would rather have something like I get from the Web Client Software Factory where the initial Presenter Class is injected for me by the Composite Web Application Block and ObjectBuilder by simply decorating a property with a [CreateNew] Attribute:


 

public partial class AddCustomer : Page, IAddCustomer
{
private AddCustomerPresenter _presenter;

[CreateNew]
public AddCustomerPresenter Presenter
{
set
{
this._presenter = value;
this._presenter.View = this;
}
}

//
}


 


That’s it. No manual wiring of dependencies. No service location. Everything is done by the Composite Web Application Block and ObjectBuilder. 


You can actually see this in my Web Client Software Factory and Enterprise Library 3.1 Sample Download as well as hear about how it happens in my Composite Web Application Block and ObjectBuilder Dependency Injection Screencast.


My point is not to discuss WCSF here, but to find out how others are doing this initial wiring. Are you just manually wiring the Presenter into the View or do you have a “framework” that does the initial wiring for you like the case with the Composite Web Application Block?


I also don’t know for sure, but I don’t believe StructureMap and Windsor have a good way out-of-the-box to inject the dependencies into the view after it has already been created as is the case for webforms. I did talk about it here some time ago as a mental exercise:


Wire-Up View-Presenter Pattern Like Web Client Software Factory – Castle Windsor for Dependency Injection


It would also be nice to have a solution that will work in a Partial Trust Environment so you can use it on small shared hosting applications as well.


This tends to be the real-world warts that you don’t often hear about with Dependency Injection and I am disappointed I haven’t been able to find a good answer. Anyone have any good ideas?

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

11 Responses to Dependency Injection and MVP in WebForms – It’s that Injection of the Presenter into the View that Stinks

  1. David Hayden says:

    I need to look at SpringFramework.net. I have heard others talk about it, but I keep forgetting to take a peek and see what it offers. Thanks for mentioning it.

  2. Glyn says:

    SpringFramework.net gives you the ability to inject dependencies directly into the views. However you would then have to have the property set the view in the presenter. I raised this issue in the support forums, and they are looking into this issue.

  3. David Hayden says:

    Jeremy,

    I re-read Jeffrey’s post about the new feature for usercontrols in StructureMap 2.0. I will give it a try this week, because it sounds pretty interesting.

    I just realized I forgot to go back to your post where you were talking about StructureMap is now 3 years old :(

    This is the scenario I was looking for StructureMap to solve. I have a page class and I want to be able to inject the Presenter Class ( or any class or service ) into it after it is already created. I don’t have control over the creation of this page class per se, but I can pass the page class to StructureMap right before the page lifecycle starts for it to analyze and inject any dependencies.

    If I could get that and partial trust support out-of-the-box for my shared-host applications and frameworks I would be overwhelmed with joy :)

  4. David Hayden says:

    Ayende,

    Igloo sounds intriguing and something I would like to try.

    It sounds very much like what I am doing with my own framework where I do the bijection using essentially a container and those 3 little lines you mentioned :) Where you are using BaseController I am looking for Presenter.

  5. David,

    One more try. You can work the other way around and go Presenter first and inject a user control in w/ StructureMap.

    Honestly, I wouldn’t be all that concerned about using service location in the view. It’s an imperfect world. When you play with MS tools and frameworks you have to play by their intended rules or suffer the consequences.

  6. David Hayden says:

    Adam,

    And that is about the best you can do without intercepting the call to the view and injecting the presenter or controller class into it before the page lifecycle starts, which is what you get from WCSF and MonoRail.

  7. Adam Webber says:

    Using WindsorContainer, I do this in Page_Init:

    presenter = Container.Resolve().Init(this);

    yes, there the view is still initiating the presenter, but the container is still doing all the auto wire-up for the presenters’ dependencies.

  8. David,
    Check this:
    http://www.ayende.com/Blog/archive/2007/06/28/Dependency-Injection-in-Web-Forms-MVC.aspx

    Rhino Igloo has this capabilities.
    Of course, it is completely undocumented, but that is another issue :-)

  9. Just to be clear… my post was on the dependencies themselves and not on dependency injection…. :)

  10. David Hayden says:

    haha…

    Yes, I know and love MonoRail but can’t always use it.

    Any other ideas? :)

  11. MonoRail.

    You did ask for an idea.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>