在使用MVP Pattern构建的ASP.NET Web表单应用程序上应用依赖注入

时间:2012-06-02 20:26:53

标签: asp.net dependency-injection mvp

我正在创建一个带有MVP模式的ASP.NET Web窗体应用程序。我的观点的结构是这样的:

public partial class ShipperView : System.Web.UI.Page, IShipperView
{
       ShipperPresenter presenter;
       public ShipperOperationsView()
        {
            IShipperOperations operations = new ShipperOperations();
            INavigator navigator = new Navigator();
            presenter = new ShipperPresenter(this,operations,navigator);  //Instantiating presenter
        }
        ...
}

我的演示者的基本结构是这样的:

public class ShipperPresenter
{
        IShipper shipperView;
        IShipperOperations operations;
        INavigator navigator;
        public ShipperPresenter(IShipperView view,IShipperOperations operations,INavigator navigator)
        {
            shipperView = view;
            this.operations = operations;
            this.navigator = navigator;
        }
        ...
}

我不想使用new关键字实例化我的演示者,我想用解析依赖项替换它。在依赖项解析期间,我想将当前视图的实例传递给依赖项解析程序。我尝试了很多,但没有得到任何满意的答案。

可以使用任何IoC容器(如StructureMap,Ninject,Unity或MEF)解决此问题吗?任何指针都会有很大的帮助。

1 个答案:

答案 0 :(得分:3)

要解决此问题,您可以使用属性注入。

首先,在DI容器中注册 ShipperOperations 导航器 ShipperPresenter

然后,在视图的Page_Load方法中,调用您选择的DI容器的resolve方法。

public class ShipperPresenter
{
        IShipper shipperView;
        IShipperOperations operations;
        INavigator navigator;
        public ShipperPresenter(IShipperOperations operations,INavigator navigator)
        {
            this.operations = operations;
            this.navigator = navigator;
        }

        public IShipper ShipperView
        {
            get { return shipperView; }
            set { shipperView = value; }
        }
        ...
}

视图看起来像这样:

public partial class ShipperView : System.Web.UI.Page, IShipperView
{
       ShipperPresenter presenter;

       protected void Page_Load(object sender, EventArgs e)
       {
           presenter = YourIOC.Resolve<ShipperPresenter>();
           presenter.ShipperView = this;
       }
       ...
}

您还可以使用工厂在运行时创建演示者,同时向其传递您选择的参数。实际上,在DI世界中,当您想要实例化具有仅在运行时已知的依赖项的对象时,这是继续进行的方法。在温莎城堡有一个很好的机制,它被称为typed factories

使用工厂,无需修改演示者类。而是为工厂创建一个界面:

public interface IShipperPresenterFactory
{
    ShipperPresenter Create(IShipper shipperView);
}

如果使用Windsor,您唯一需要做的就是将此接口注册为类型工厂。对于其他DI容器,您必须在内部实现一个使用DI容器来解析演示者的类。

然后,视图的Page_Load方法将使用工厂:

protected void Page_Load(object sender, EventArgs e)
{
    var factory = YourIOC.Resolve<IShipperPresenterFactory>();
    presenter = factory.Create(this);
}