c# - 使用 StructureMap 在 Model-View-Presenter 模式中进行 Presenter 注入(inject)

标签 c# dependency-injection structuremap mvp

我已经实现了我自己的模型 View 展示器模式副本(按照 Web 客户端软件工厂的思路),因此我可以利用我自己的 DI 框架,而不是绑定(bind)到我遇到过很多问题的 WCSF 的 ObjectBuilder。我想出了一些方法来做到这一点,但没有一个特别让我开心。我想知道是否还有其他人有其他想法。

解决方案 #1a

使用 HttpModule 拦截 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

在页面加载时调用构建而不是使用 HttpModule

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

通过 Property 访问 presenter 允许 Getter 在需要时进行 BuildUp。

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,并创建一个 layer supertype对于所有页面,为了干燥演示者初始化更多一点。像这样:

页面代码:

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 应该是抽象还是虚拟

Template Method最初声明该方法应该是抽象的,以强制子类实现它,遵守父类(super class)契约。 (参见“大富翁”<“游戏”的维基百科示例)。

另一方面,在这种特殊情况下,我们不想强制用户类重新定义我们的方法,而是给它机会这样做。如果你将它声明为抽象的,许多类将不得不重新定义该方法只是为了让它为空(这显然是一种代码味道)。所以我们提供了一个合理的默认值(什么都不做)并使该方法成为虚拟方法。

关于c# - 使用 StructureMap 在 Model-View-Presenter 模式中进行 Presenter 注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/514638/

相关文章:

spring - 我可以在 groovy 中编写 spring java 测试吗?

SQL Azure : More Intermittent Timeouts

c# - 有没有C#静态分析工具可以抓取不满足功能需求的API?

c# - Dns.GetHostAddresses 真的取回所有已注册的 IP 吗?

c# - Ghostscript.NET 光栅器内存不足

AngularJS:服务vs提供者vs工厂

Spring Java配置: Create Bean From Dynamic Class Name

.net - 如何在 StructureMap Registy 构造函数中获取实例?

asp.net - 使用 StructureMap3 在 MVC 应用程序中注入(inject)当前用户的依赖项

c# - 在 gridview 中,updatepanel 不工作