我正在创建一个带有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)解决此问题吗?任何指针都会有很大的帮助。
答案 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);
}