主持人注射用StructureMap模型 - 视图 - 演示模式
-
21-08-2019 - |
题
我实现我自己的模型视图演示模式(在Web客户端软件工厂的静脉)的副本,以便我可以利用我自己的DI框架,而不是依赖于WCSF的ObjectBuilder的,我曾与许多问题。我已经想出一些方法来做到这一点,但他们没有特别让我高兴。我想知道如果任何人有一些其他的想法。
溶液#1A
使用HTTP模块拦截context.PreRequestHandlerExecute调用ObjectFactory.BuildUp(HttpContext.Current.Handler)
public partial class _Default : Page, IEmployeeView
{
private EmployeePresenter _presenter;
private EmployeePresenter Presenter
{
set
{
_presenter = value;
_presenter.View = this;
}
}
}
溶液#1b的
在页面加载呼叫堆积,而不是使用的HTTP模块
public partial class _Default : Page, IEmployeeView
{
private EmployeePresenter _presenter;
private EmployeePresenter Presenter
{
set
{
_presenter = value;
_presenter.View = this;
}
}
protected void Page_Load(object sender, EventArgs e)
{
ObjectFactory.BuildUp(this);
}
}
溶液#1C
通过属性访问演示允许吸气剂至堆积如果需要的话。
public partial class _Default : Page, IEmployeeView
{
private EmployeePresenter _presenter;
public EmployeePresenter Presenter
{
get
{
if (_presenter == null)
{
ObjectFactory.BuildUp(this);
}
return _presenter;
}
set
{
_presenter = value;
_presenter.View = this;
}
}
}
溶液#2
public partial class _Default : Page, IEmployeeView
{
private EmployeePresenter _presenter;
private EmployeePresenter Presenter
{
get
{
if (_presenter == null)
{
_presenter = ObjectFactory.GetInstance<EmployeePresenter>();
_presenter.View = this;
}
return _presenter;
}
}
}
溶液#2B
public partial class _Default : Page, IEmployeeView
{
private EmployeePresenter _presenter;
private EmployeePresenter Presenter
{
get
{
if (_presenter == null)
{
Presenter = ObjectFactory.GetInstance<EmployeePresenter>();
}
return _presenter;
}
set
{
_presenter = value;
_presenter.View = this;
}
}
}
修改强>:添加溶液1C,2B
解决方案
我最好使用溶液#1b和在全部页创建层超型,以干燥演示初始化多一点。像这样:
页面代码:
public partial class _Default : AbstractPage, IEmployeeView
{
private EmployeePresenter presenter;
private EmployeePresenter Presenter
{
set
{
presenter = value;
presenter.View = this;
}
}
protected override void Do_Load(object sender, EventArgs args)
{
//do "on load" stuff
}
}
摘要页面代码:
public abstract class AbstractPage : Page
{
protected void Page_Load(object sender, EventArgs e)
{
ObjectFactory.BuildUp(this);
this.Do_Load(sender,e);
//template method, to enable subclasses to mimic "Page_load" event
}
//Default Implementation (do nothing)
protected virtual void Do_Load(object sender, EventArgs e){}
}
通过这个解决方案,您有演示初始化(由ObjectFactory的创建)一类只,如果以后需要修改它,你可以很容易地做到这一点。
修改强>
<强>应该Do_Load是抽象或虚拟吗
模板方法最初指出该方法应该是抽象的,以迫使子类实现它秉承了超合同。 (见 “专卖”< “游戏” 的维基百科例子)。
在这个特定的情况下,另一方面,我们不希望强迫用户类重新定义我们的方法,但给它这样做的机会。如果你把它声明抽象,许多类将不得不重新定义方法只是为了让它空(这显然是一个代码味道)。因此,我们提供了一个合理的默认(什么都不做),使虚拟方法
其他提示
我已经建立了像我自己的MVP框架了。我找到了最好的办法,我是使用仿制药与基础页面类。通过在泛型类定义指定主讲的类型,我可以错过了大部分的代码的其中您的每一个建议要求。
不过,也有一些事情,我不喜欢这样做这种方式。类定义可以最终看起来相当复杂,并且不容易阅读的新手。我还没有完全制定出使用事件模型,在基本页面的好办法。
对不起,我没有为你的代码在这里,但如果你想我可以张贴一些给你。我也有一个老版本张贴在www.codeplex.com/aspnetmvp的代码,你应该想看看它是如何工作的。
我已经使用碱页类:
protected override void OnInit(EventArgs e)
{
StructureMap.ObjectFactory.BuildUp(this);
base.OnInit(e);
}
在基类的方法适用于用户的控制,以及,单独让我从模块(不想有2种方式来进行设置)。 对于页面是
public partial class Employee : View, IEmployeeView
{
public ViewPresenter Presenter { get; set; }
private void Page_Load(object sender, EventArgs e){}
}
我注入通过构造的视图。为了避免在structuremap配置循环引用问题,只要使用这种辅助方法:
static T GetView<T>()
{
return (T) HttpContext.Current.Handler;
}
在所述structuremap配置使用约定演示者和视图注入两者。
感谢大家的非常宝贵的意见。你的回答每一个给了我宝贵的想法,在我的最终解决方案结合在一起,这就是我想出了:
public abstract class ViewBasePage<TPresenter, TView> :
Page where TPresenter : Presenter<TView>
{
protected TPresenter _presenter;
public TPresenter Presenter
{
set
{
_presenter = value;
_presenter.View = GetView();
}
}
/// <summary>
/// Gets the view. This will get the page during the ASP.NET
/// life cycle where the physical page inherits the view
/// </summary>
/// <returns></returns>
private static TView GetView()
{
return (TView) HttpContext.Current.Handler;
}
protected override void OnPreInit(EventArgs e)
{
ObjectFactory.BuildUp(this);
base.OnPreInit(e);
}
}
和我的原始页面继承:
public partial class _Default :
ViewBasePage<EmployeePresenter, IEmployeeView>, IEmployeeView
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
_presenter.OnViewInitialized();
}
_presenter.OnViewLoaded();
Page.DataBind();
}
#region Implementation of IEmployeeView
...
#endregion
}