Asp.Net开发架构设计(二)
上回說到,我們配置了一下UnityConfig層,在這個層中定義了一個IContainerAccessor的接口和一個返回IUnityContainer類型的方法,這個方法的主要作用就是把Service層中的接口類和Business層中的接口實現類裝配到UnityContainer中并返回,也就是指定那個接口實現類去實現某個接口類(暈,好像有點繞口啊)。
?
Xiaozhuang.UnityConfignamespace?Xiaozhuang.UnityConfig
{
????
????????public?interface?IContainerAccessor
????????{
????????????IUnityContainer?Container?{?get;?}
????????}
????????public?class?UnityContainerConfig
????????{
????????????public?IUnityContainer?GetIUnityContainer()
????????????{
????????????????IUnityContainer?container?=?new?UnityContainer();
????????????????container.RegisterType<IQueryEmployeeService,?QueryEmployeeBusiness>();
????????????????return?container;
????????????}
????????}
????
}
?
好了,現在終于輪到Web層了,要實現在Asp.Net頁面中直接調用能夠服務接口而不用從Unity容器中再去取出來,就要把Unity容器中的接口注入到頁面中去,分兩步走:第一步,在Global.Asax.cs中實現UnityConfig層中的IContainerAccessor接口,并把UnityConfig層返回的IUnityContainer賦值給實現接口的全局靜態屬性。
?
Codenamespace?Xiaozhuang.Web
{
????public?class?Global?:?System.Web.HttpApplication,?IContainerAccessor
????{
????????Members#region?Members
????????private?static?IUnityContainer?_container;
????????#endregion
????????Properties#region?Properties
????????/**////?<summary>
????????///?The?Unity?container?for?the?current?application
????????///?</summary>
????????public?static?IUnityContainer?Container
????????{
????????????get
????????????{
????????????????return?_container;
????????????}
????????????set
????????????{
????????????????_container?=?value;
????????????}
????????}
????????#endregion
????????IContainerAccessor?Members#region?IContainerAccessor?Members
????????/**////?<summary>
????????///?Returns?the?Unity?container?of?the?application?
????????///?</summary>
????????IUnityContainer?IContainerAccessor.Container
????????{
????????????get
????????????{
????????????????return?Container;
????????????}
????????}
????????#endregion
????????Application?Events#region?Application?Events
????????protected?void?Application_Start(object?sender,?EventArgs?e)
????????{
????????????BuildContainer();
????????}
????????protected?void?Session_Start(object?sender,?EventArgs?e)
????????{
????????}
????????protected?void?Application_BeginRequest(object?sender,?EventArgs?e)
????????{
????????}
????????protected?void?Application_AuthenticateRequest(object?sender,?EventArgs?e)
????????{
????????}
????????protected?void?Application_Error(object?sender,?EventArgs?e)
????????{
????????}
????????protected?void?Session_End(object?sender,?EventArgs?e)
????????{
????????}
????????protected?void?Application_End(object?sender,?EventArgs?e)
????????{
????????????CleanUp();
????????}
????????#endregion
????????Methods#region?Methods
????????private?static?void?BuildContainer()
????????{
????????????UnityContainerConfig?config?=?new?UnityContainerConfig();
????????????Container?=?config.GetIUnityContainer();
????????}
????????private?static?void?CleanUp()
????????{
????????????if?(Container?!=?null)
????????????{
????????????????Container.Dispose();
????????????}
????????}
????????#endregion
????}
}
接下來要把UnityContainer中的接口注入到頁面中去。建立一個BasePage的泛型類,先獲取到從Gloab.Asax傳過來的應用程序實例,轉化為UnityContainer,利用BuildUp方法注入到頁面中去。
?
BasePagenamespace?Foresee.Web
{
????public?abstract?class?BasePage<T>?:?Page?where?T?:?class
????{
????????protected?override?void?OnPreInit(EventArgs?e)
????????{
????????????InjectDependencies();
????????????base.OnPreInit(e);
????????}
????????protected?virtual?void?InjectDependencies()
????????{
????????????var?context?=?HttpContext.Current;
????????????if?(context?==?null)
????????????{
????????????????ClientScript.RegisterClientScriptBlock(this.GetType(),?"context",?"<script>alert('當前Http上下文為空,請與系統管理員聯系!');</script>");
????????????}
????????????var?accessor?=?context.ApplicationInstance?as?IContainerAccessor;
????????????if?(accessor?==?null)
????????????{
????????????????ClientScript.RegisterClientScriptBlock(this.GetType(),?"context",?"<script>alert('當前應用程序實例為空,請與系統管理員聯系!');</script>");
????????????}
????????????var?container?=?accessor.Container;
????????????if?(container?==?null)
????????????{
????????????????ClientScript.RegisterClientScriptBlock(this.GetType(),?"context",?"<script>alert('未找到依賴注入容器,請與系統管理員聯系!');</script>");
????????????}
????????????container.BuildUp(this?as?T);
????????}
????}
}
我們不止在頁面中要調用接口,也要在UserControl中調用,那么我們就參照上面的頁面基類建立一個UserControl的泛型基類。
?
BaseUserControlnamespace?Foresee.Web
{
????public?abstract?class?BaseUserControl<T>?:?UserControl?where?T?:?class
????{
????????protected?override?void?OnInit(EventArgs?e)
????????{
????????????InjectDependencies();
????????????base.OnInit(e);
????????}
????????protected?virtual?void?InjectDependencies()
????????{
????????????var?context?=?HttpContext.Current;
????????????if?(context?==?null)
????????????{
????????????????this.Page.ClientScript.RegisterClientScriptBlock(this.Page.GetType(),?"context",?"<script>alert('當前Http上下文為空,請與系統管理員聯系!');</script>");
????????????}
????????????var?accessor?=?context.ApplicationInstance?as?IContainerAccessor;
????????????if?(accessor?==?null)
????????????{
????????????????this.Page.ClientScript.RegisterClientScriptBlock(this.Page.GetType(),?"context",?"<script>alert('當前應用程序實例為空,請與系統管理員聯系!');</script>");
????????????}
????????????var?container?=?accessor.Container;
????????????if?(container?==?null)
????????????{
????????????????this.Page.ClientScript.RegisterClientScriptBlock(this.Page.GetType(),?"context",?"<script>alert('未找到依賴注入容器,請與系統管理員聯系!');</script>");
????????????}
????????????container.BuildUp(this?as?T);
????????}
????}
}
接下來我們建立一個UserControl文件,在里面調用查詢雇員的服務接口,并綁定到ListView控件上,具體代碼如下:
?
Codenamespace?Xiaozhuang.Web
{
????public?partial?class?EmployeeList?:?BaseUserControl<EmployeeList>
????{
????????
????????#region?Properties
????????[Dependency]
????????public?IQueryEmployeeService?instance?{?set;?get;?}
????????public?QueryEntry?queryentry?{?set;?get;?}
????????#endregion
????????protected?void?Page_Load(object?sender,?EventArgs?e)
????????{
????????????if?(!IsPostBack)
????????????{
????????????????try
????????????????{
????????????????????ListView1.DataSource?=?instance.QueryEmployee(queryentry);
????????????????????ListView1.DataBind();
????????????????}
????????????????catch?
????????????????{
???????????????????
???????????????????Response.Write("系統運行錯誤,請與管理員聯系!");
????????????????}
????????????}
????????}
????}
}
這個EmployeeList繼承自BaseUserControl<T>.UserControl基類,這樣這個用戶控件就可以實現注入了,我們只需要在屬性上增加Dependency標記就可以用屬性注入的方式來調用接口方法,當然你也可以通過方法注入的方式來實現。
接下來我們要用Asp.net Ajax調用這個UserControl來生成HTML,給頁面上使用,我們先建立兩個類ControlPage和ViewManager
?
Codenamespace?Xiaozhuang.Web
{
????public?class?ControlPage?:?Page
????{
????????public?override?void?VerifyRenderingInServerForm(Control?control)
????????{
????????????//base.VerifyRenderingInServerForm(control);
????????}
????}
}
namespace?Xiaozhuang.Web
{
????///?<summary>
????///?A?generic?user?control?rendering?helper,?basically?you?initialise?the?view?manager?and?
????///?call?render?to?render?that?control,?but?the?benifit?of?this?version?is?you?can?access?the?control
????///?the?view?manager?is?rendering?and?can?set?custom?properties?etc.
????///?</summary>
????///?<typeparam?name="T">The?type?of?the?control?you?are?rendering</typeparam>
????public?class?ViewManager<T>?where?T?:?Control
????{
????????#region?Properties
????????private?T?_control?=?default(T);
????????///?<summary>
????????///?Gives?you?access?to?the?control?you?are?rendering?allows
????????///?you?to?set?custom?properties?etc.
????????///?</summary>
????????public?T?Control
????????{
????????????get
????????????{
????????????????return?_control;
????????????}
????????}
????????//?Used?as?a?placeholder?page?to?render?the?control?on.
????????private?ControlPage?_holder?=?null;
????????#endregion
????????#region?Constructor
????????///?<summary>
????????///?Default?constructor?for?this?view?manager,?pass?in?the?path?for?the?control
????????///?that?this?view?manager?is?render.
????????///?</summary>
????????///?<param?name="inPath"></param>
????????public?ViewManager(string?path)
????????{
????????????//Init?the?holder?page
????????????_holder?=?new?ControlPage();
????????????//?Create?an?instance?of?our?control
????????????_control?=?(T)_holder.LoadControl(path);
????????????//?Add?it?to?our?holder?page.
????????????_holder.Controls.Add(_control);
????????}
????????#endregion
????????#region?Rendering
????????///?<summary>
????????///?Renders?the?current?control.
????????///?</summary>
????????///?<returns></returns>
????????public?string?Render()
????????{
????????????StringWriter?sw?=?new?StringWriter();
????????????//?Execute?the?page?capturing?the?output?in?the?stringwriter.
????????????HttpContext.Current.Server.Execute(_holder,?sw,?false);
????????????//?Return?the?output.
????????????return?sw.ToString();
????????}
????????#endregion
????}
}
ControlPage類是一個簡單的繼承Page的類,里面重載VerifyRenderingInServerForm方法的作用是防止在UserControl生成HTML的時候如果UserControl中有服務器控件而出現的“服務器控件必須放在Form ruanat=‘server’”的錯誤!ViewManager類的作用是把在服務器端UserControl裝在ControlPage頁面中用Excute方法執行一遍并用Render方法獲取到執行后輸出的HTML字符串。
接下來我們到頁面中去,在頁面類中建立一個輸出HTML的靜態帶WebService標記的方法,如下
?
Code[WebMethod()]
????????public?static?string?GetDataPage(int?page,?string?departmentID,?string?EmpName,?string?EmpAge)
????????{
????????????//?Create?an?instance?of?our?viewmanager.
????????????ViewManager<EmployeeList>?man?=?new?ViewManager<EmployeeList>("~/EmployeeList.ascx");
????????????QueryEntry?queryentry?=?new?QueryEntry();
????????????queryentry.DepartmentID?=?departmentID;
????????????queryentry.EmployeeName?=?EmpName;
????????????queryentry.EmployeeAge?=?EmpAge;
????????????man.Control.queryentry?=?queryentry;
????????????return?man.Render();
????????}
這個方法的作用是吧查詢的參數傳遞給EmployeeList用戶控件,通過ViewManager執行并輸出HTML字符串,在Aspx頁面中用Asp.Net Ajax代碼來調用這個方法,并把返回的html填充到相應的Div中。如下
?
Code<script?type="text/javascript">
????var?currentPage?=?0;????
????????function?LoadPage(page)?{
?????????var?departmentID?=?document.getElementById("txtDept").value;
??????????var?empName?=?document.getElementById("txtName").value;
???????????var?empAge?=?document.getElementById("txtAge").value;
????????????PageMethods.GetDataPage(page,departmentID,empName,empAge,?function(result)?{
????????????????//?We?loaded?our?data?populate?our?div.????????????????
????????????????document.getElementById("DivContent").innerHTML?=?result;
????????????},
????????????function(error)?{
????????????????alert(error.get_message());
????????????});
????????}
??????????Sys.Application.add_load(LoadPage);
????</script>
?
至此寫完,其實這個生成html的方法我用了很久了,本來這次是寫架構設計的,給扯到這上面來了,也許這也算是架構設計的一部分吧。
運行效果如下:
轉載于:https://www.cnblogs.com/xiaozhuang/archive/2008/08/21/1272963.html
總結
以上是生活随笔為你收集整理的Asp.Net开发架构设计(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 欢乐颂2的我们是谁唱的啊?
- 下一篇: 夜微凉琴飞扬是谁写的啊?