上回说到,我们配置了一下UnityConfig层,在这个层中定义了一个IContainerAccessor的接口和一个返回IUnityContainer类型的方法,这个方法的主要作用就是把Service层中的接口类和Business层中的接口实现类装配到UnityContainer中并返回,也就是指定那个接口实现类去实现某个接口类(晕,好像有点绕口啊)。

 

 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赋值给实现接口的全局静态属性。

 

}

接下来要把UnityContainer中的接口注入到页面中去。建立一个BasePage的泛型类,先获取到从Gloab.Asax传过来的应用程序实例,转化为UnityContainer,利用BuildUp方法注入到页面中去。

 

 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的泛型基类。

 

 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控件上,具体代码如下:

 

 Xiaozhuang.Web
{
    public partial class EmployeeList : BaseUserControl<EmployeeList>
    {
        
        
#region Properties

        [Dependency]
        
public IQueryEmployeeService instance { setget; }

        
public QueryEntry queryentry { setget; }

        
#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

 

 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标记的方法,如下

 

[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中。如下

 


    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的方法我用了很久了,本来这次是写架构设计的,给扯到这上面来了,也许这也算是架构设计的一部分吧。
运行效果如下:

Asp.Net开发架构设计(二)

相关文章:

  • 2021-07-27
  • 2021-11-18
  • 2021-12-31
  • 2021-04-10
  • 2021-11-18
  • 2022-02-04
  • 2021-07-22
  • 2021-06-19
猜你喜欢
  • 2022-12-23
  • 2021-12-31
  • 2021-11-23
  • 2022-12-23
相关资源
相似解决方案