在ASP上应用依赖注入。NET web表单应用程序使用MVP模式构建

时间:2023-02-09 21:14:29

I am creating an ASP.NET Web forms application with MVP pattern. The structure of my view is something like this:

我正在创建一个ASP。NET Web表单应用与MVP模式。我的观点是这样的:

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
        }
        ...
}

The basic structure of my presenter is something like this:

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

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;
        }
        ...
}

I don't want to instantiate my presenter using the new keyword, I would like to replace it with resolving dependency. During the dependency resolution, I want to pass the instance of the present view to the dependency resolver. I tried searching a lot on this but did not get any satisfactory answer.

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

Can this issue be resolved using any of the IoC containers like StructureMap, Ninject, Unity or MEF? Any pointer would be of great help.

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

1 个解决方案

#1


2  

To solve this problem you could use property injection.

要解决这个问题,可以使用属性注入。

First, register ShipperOperations, Navigator and ShipperPresenter in the DI container.

首先,在DI容器中注册ShipperOperations、Navigator和ShipperPresenter。

Then, in the Page_Load method of your view, invoke the resolve method of the DI container of your choice.

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

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; }
        }
        ...
}

And the view would look like this:

视图是这样的

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;
       }
       ...
}

You could also use a factory to create the presenter at runtime, while passing it the parameters of your choice. In fact, in a DI world, this is THE way to proceed when you want to instantiate objects with dependencies that are only known at runtime. There is a nice mechanism for this in Castle Windsor, it's called typed factories.

您还可以使用工厂在运行时创建演示者,同时传递您选择的参数。事实上,在DI世界中,当您希望用只在运行时才知道的依赖项实例化对象时,这是一种继续的方式。在温莎堡有一个很好的机制,叫做类型化工厂。

Using a factory, no need to modify the presenter class. Instead, create an interface for the factory:

使用工厂,无需修改presenter类。相反,为工厂创建一个接口:

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

If using Windsor, the only thing that you have to do is to register this interface as a typed factory. With other DI containers, you will have to implement a class that uses the DI container internally to resolve the presenter.

如果使用Windsor,您只需将该接口注册为类型化工厂。对于其他DI容器,您必须实现一个类,该类在内部使用DI容器来解析演示程序。

The Page_Load method of the view would then use the factory like this:

视图的Page_Load方法将使用如下工厂:

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

#1


2  

To solve this problem you could use property injection.

要解决这个问题,可以使用属性注入。

First, register ShipperOperations, Navigator and ShipperPresenter in the DI container.

首先,在DI容器中注册ShipperOperations、Navigator和ShipperPresenter。

Then, in the Page_Load method of your view, invoke the resolve method of the DI container of your choice.

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

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; }
        }
        ...
}

And the view would look like this:

视图是这样的

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;
       }
       ...
}

You could also use a factory to create the presenter at runtime, while passing it the parameters of your choice. In fact, in a DI world, this is THE way to proceed when you want to instantiate objects with dependencies that are only known at runtime. There is a nice mechanism for this in Castle Windsor, it's called typed factories.

您还可以使用工厂在运行时创建演示者,同时传递您选择的参数。事实上,在DI世界中,当您希望用只在运行时才知道的依赖项实例化对象时,这是一种继续的方式。在温莎堡有一个很好的机制,叫做类型化工厂。

Using a factory, no need to modify the presenter class. Instead, create an interface for the factory:

使用工厂,无需修改presenter类。相反,为工厂创建一个接口:

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

If using Windsor, the only thing that you have to do is to register this interface as a typed factory. With other DI containers, you will have to implement a class that uses the DI container internally to resolve the presenter.

如果使用Windsor,您只需将该接口注册为类型化工厂。对于其他DI容器,您必须实现一个类,该类在内部使用DI容器来解析演示程序。

The Page_Load method of the view would then use the factory like this:

视图的Page_Load方法将使用如下工厂:

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