注入依赖关系:使用MVP模式的ASP.net Webforms

时间:2017-01-22 03:13:11

标签: c# asp.net dependency-injection webforms mvp

我正努力使用ASP.net实现依赖注入。我在winforms中创建了一个使用MVP被动视图模式的简单项目。我在网上看到了这种模式的很多变化。我看到的许多示例都让View负责实例化Presenter。其他人让Presenter创建视图。我选择先运行一个单独的winforms项目,然后单击一个按钮,创建我的View,Model和Presenter,并将视图传递给Presenters构造函数。这让我避免三层之间的直接引用,这样它们只保留对接口库的引用。到目前为止一切都那么好,一切都按预期运作我听说如果我设法将视图保持为“愚蠢的”#34;尽管主要逻辑主持在Presenter中,但转移到ASP.net并不会太困难。

我的下一步是在ASP.net webforms中重新创建解决方案,只需用代码隐藏实现我的IView接口的webform替换UI / View。我的所有类都成功编译没有问题,但是当我运行程序时,我得到一个NullReferenceException:对象引用未设置为对象的实例。当Presenter尝试设置文本框的视图属性时,会发生这种情况。似乎尚未创建文本框。如果我将webforms应用程序的开始序列与winforms应用程序进行比较,那么我会看到winforms应用程序在创建时运行View并注册每个控件和属性。即使我对两者使用相同的方法,webform也不会发生这种情况。

这是首先加载的单独的webform:

using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using POCOClassLibrary;
using InterfaceLibrary;
using AppointmentModel;
using AppointmentsPresenter;
using WebFormMVP;

namespace WebDriver
{
    public partial class WebDriver : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void btnLaunch_Click(object sender, EventArgs e)
        {
            IAppointmentView view = new frmAppointmentView();
            IAppointmentModel<Appointment> model = new AppointmentsModel();
            new AppointmentPresenter(view, model);

            view.Show();
        }
    }
}

加载并显示按钮,然后单击它到达Presenter类(此处未显示):

namespace AppointmentsPresenter
{
    //The Presenter is the go-between for the View and Model.  It sets the properties in the View to be displayed and
    //Stores and Gets the data from the Model. It responds to events raised by the View.
    public class AppointmentPresenter
    {
        private readonly IAppointmentView _view;                //references the View Interface
        private readonly IAppointmentModel<Appointment> _model; //references the Model Interface
        /// <summary>
        /// The List of Appointments is created and stored in the Model.  
        /// In reality we would be using a Database and not a List<>.
        /// </summary>
        private List<Appointment> appointments;

        //maintenace of state:
        private int currentIndex = 0;
        private bool isNew = true;

        private string navigationstatus = "next";
        ///Presenter constuctor which allows us to pass in the View and Model as interfaces - exposing their events,
        /// methods and properties.    
        public AppointmentPresenter(IAppointmentView view, IAppointmentModel<Appointment> model)  //dependencies passed into contructor 
        {

            this._view = view;
            this._model = model;

            Initialize();
        }
        private void Initialize()
        {
            appointments = _model.CreateList();         //Creates and returns List of Appointments in the Model
                                                        //lets us manipulate the List that the Model creates.
            _view.SaveAppointment += Save_Appointment;  //Subscribe to the View events.
            _view.NewAppointment += New_Appointment;
            _view.PreviousAppointment += Previous_Appointment;
            _view.NextAppointment += Next_Appointment;
            _view.YesButtonClick += YesButtonClicked;
            _view.NoButtonClick += NoButtonClicked;

            BlankAppointment();
            _view.StatusChange = "Ready";
        }
        private void BlankAppointment()
        {
            _view.AppointmentName = string.Empty;
            _view.Priority = "Low";
            _view.StartDate = null;
            _view.DueDate = null;
            _view.CompletionDate = null;
            _view.Completed = false;
        }

当它到达BlankAppointment()方法并尝试设置_view.AppointmentName属性时,就会出现错误并抛出NullReferenceException。

以下是一些View,我试图删除大部分逻辑,只是在这里实现属性和事件:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using InterfaceLibrary;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition;

namespace WebFormMVP 
{
    public partial class frmAppointmentView : System.Web.UI.Page, IAppointmentView
    {   
        public string AppointmentName
        {
            get { return txtAppointment.Text; }
            set { txtAppointment.Text = value; }
        }
        public string Priority
        {
            get { return cboPriority.Text; }
            set { cboPriority.Text = value; }
        }
        public string StartDate
        {
            get { return txtStartDate.Text; }
            set { txtStartDate.Text = value; }
        }
        public string DueDate
        {
            get { return txtDueDate.Text; }
            set { txtDueDate.Text = value; }
        }
        public string CompletionDate
        {
            get { return txtCompletionDate.Text; }
            set { txtCompletionDate.Text = value; }
        }
        public bool Completed
        {
            get { return chkCompleted.Checked; }
            set { chkCompleted.Checked = value; }
        }
        public bool isDirty { get; set; }

        public bool NewButtonVisible
        {
            set { btnNew.Visible = value; }
        }
        public bool SaveButtonVisible
        {
            set { btnSave.Visible = value; }
        }
        public bool NextButtonVisible
        {
            set { btnNext.Visible = value; }
        }
        public bool PreviousButtonVisible
        {
            set { btnPrevious.Visible = value; }
        }
        public bool YesButtonVisible
        {
            set { btnYes.Visible = value; }
        }
        public bool NoButtonVisible
        {
            set { btnNo.Visible = value; }
        }
        public string StatusChange
        {
            set { lblStatus.Text = value; }
        }

        public event EventHandler<EventArgs> NewAppointment;
        public event EventHandler<EventArgs> NextAppointment;
        public event EventHandler<EventArgs> NoButtonClick;
        public event EventHandler<EventArgs> PreviousAppointment;
        public event EventHandler<EventArgs> SaveAppointment;
        public event EventHandler<EventArgs> YesButtonClick;

        public void Show()
        {
            this.Show();
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            this.isDirty = false;
        }
        private void btnSave_Click(object sender, EventArgs e)
        {
            if (SaveAppointment != null)
            {
                SaveAppointment(this, EventArgs.Empty);
            }
        }
        private void btnNew_Click(object sender, EventArgs e)
        {
            if (NewAppointment != null)
            {
                NewAppointment(this, EventArgs.Empty);
            }
        }
        private void btnPrevious_Click(object sender, EventArgs e)
        {
            if (PreviousAppointment != null)
            {
                PreviousAppointment(this, EventArgs.Empty);
            }
        }
        private void btnNext_Click(object sender, EventArgs e)
        {
            if (NextAppointment != null)
            {
                NextAppointment(this, EventArgs.Empty);
            }
        }
        private void btnYes_Click(object sender, EventArgs e)
        {
            if (YesButtonClick != null)
            {
                YesButtonClick(this, EventArgs.Empty);
            }
        }
        private void btnNo_Click(object sender, EventArgs e)
        {
            if (NoButtonClick != null)
            {
                NoButtonClick(this, EventArgs.Empty);
            }
        }
        private void txtAppointment_TextChanged(object sender, EventArgs e)
        {
            this.isDirty = true;
        }
        private void cboPriority_SelectedIndexChanged(object sender, EventArgs e)
        {
            this.isDirty = true;
        }
        private void txtStartDate_TextChanged(object sender, EventArgs e)
        {
            this.isDirty = true;
        }
        private void txtDueDate_TextChanged(object sender, EventArgs e)
        {
            this.isDirty = true;
        }
        private void txtCompletionDate_TextChanged(object sender, EventArgs e)
        {
            this.isDirty = true;
        }
        private void chkCompleted_CheckedChanged(object sender, EventArgs e)
        {
            this.isDirty = true;
        }
    }
}

到目前为止形成我的搜索似乎在webforms中实现对Presenters构造函数的注入可能存在问题,并且我需要覆盖PageHandler类来解析依赖项,但是到目前为止我看过的示例有首先由View创建Presenter。我想尽可能避免这种情况,并使用单独的webform页面来实例化Model,View,Presenter并以这种方式解决依赖关系。

道歉,如果我还不清楚 - 我在MVP和ASP.net Webforms的背后都非常湿透。任何建议都会非常感激,因为我很困惑如何解决这个难题。 ; D

0 个答案:

没有答案