使用Autofac与ASP.NET和MVP模式

时间:2021-04-09 21:11:46

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

我正在尝试将Autofac集成到现有的ASP.NET Web应用程序中。

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.

页面遵循MVP模式。每个页面都为Presenter实现了View和delegate功能。 View通过构造函数注入Presenter。

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?

我能够注册Presenter和View并且页面加载正常,但是当发生回发时,视图上的用户控件为null。看起来Autofac创建了一个新的Page实例来提供给演示者,而不是给它实例真实的Page实例。有没有办法让Page实例在Autofac中注册?

Has anyone use Autofac with ASP.NET and MVP?

有没有人在ASP.NET和MVP中使用Autofac?

Thanks!

2 个解决方案

#1


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

有一个更好的办法。首先,启用Web集成模块。这将启用自动属性注入到Page实例。

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:

所以,首先你需要presenter工厂,它是一个具有必要参数的委托:

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>();

#2


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.

我想出了一个解决方案。基本上,您将在Page_PreInit事件期间注册页面实例,然后调用容器以注入依赖项。防爆。

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.

我不确定是否有更好的方法,但这似乎有效。

#1


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

有一个更好的办法。首先,启用Web集成模块。这将启用自动属性注入到Page实例。

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:

所以,首先你需要presenter工厂,它是一个具有必要参数的委托:

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>();

#2


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.

我想出了一个解决方案。基本上,您将在Page_PreInit事件期间注册页面实例,然后调用容器以注入依赖项。防爆。

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.

我不确定是否有更好的方法,但这似乎有效。