views:

634

answers:

2

I'm trying to integrate Autofac into an exsisting ASP.NET web application.

The pages follow the MVP pattern. Each page implements a View and delegate functionality to a Presenter. The View is injected into the Presenter thru the constructor.

I was able to register the Presenter and View and the page loads fine but when a postback happens the user controls on the view are null. It seems that Autofac creates a new instance of the Page to give to the presenter instead of giving it the instance real Page instance. Is there a way to have Page instances registered with Autofac?

Has anyone use Autofac with ASP.NET and MVP?

Thanks!

A: 

I figured out a solution. Basically, you would register the page instance during the Page_PreInit event and then call the container to inject the dependencies. Ex.

public partial class IOCTest : System.Web.UI.Page, IIOCTestView
{

    protected void Page_PreInit(object sender, EventArgs e)
    {
        var containerProviderAccessor = (IContainerProviderAccessor)HttpContext.Current.ApplicationInstance;
        var containerProvider = containerProviderAccessor.ContainerProvider;

        var builder = new ContainerBuilder();
        builder.Register(this).ExternallyOwned().As<IIOCTestView>();

        builder.Build(containerProvider.RequestContainer);

        containerProvider.RequestContainer.InjectProperties(this);
    }

    public IOCTestPresenter Presenter { get; set; }

I'm not sure if there is a better way, but this seems to work.

mwissman
A: 

There is a better way. First, enable the Web integration module. This will enable automatic property injection into the Page instance.

Since your presenter needs the view in its constructor, your page should take a dependency on a presenter factory instead of the presenter itself.

So, first you need the presenter factory, which is a delegate with the necessary parameters:

public delegate IOCTestPresenter IOCTestPresenterFactory(IIOCTestView view);

This delegate must match the parameters (type and name) of the presenter constructor:

public class IOCTestPresenter
{
     public IOCTestPresenter(IIOCTestView view)
     {
     }
}

In your view, add a property receiving the factory delegate, and use the delegate to create the presenter:

public partial class IOCTest
{
     public IOCTestPresenterFactory PresenterFactory {get;set;}

     protected void Page_Load(object sender, EventArgs e)    
     {
           var presenter = PresenterFactory(this);
     }
}

In your container setup you will have to make the following registrations:

builder.Register<IOCTestPresenter>().FactoryScoped();
builder.RegisterGeneratedFactory<IOCTestPresenterFactory>();
Peter Lillevold