当前位置: 首页 > 编程日记 > 正文

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

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

ContractedBlock.gifExpandedBlockStart.gifXiaozhuang.UnityConfig
namespace 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赋值给实现接口的全局静态属性。

ContractedBlock.gifExpandedBlockStart.gifCode
namespace Xiaozhuang.Web
ExpandedBlockStart.gifContractedBlock.gif
{
    
public class Global : System.Web.HttpApplication, IContainerAccessor
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{

ContractedSubBlock.gifExpandedSubBlockStart.gif        
Members#region Members

        
private static IUnityContainer _container;

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
Properties#region Properties

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// The Unity container for the current application
        
/// </summary>

        public static IUnityContainer Container
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return _container;
            }

            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                _container 
= value;
            }

        }


        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
IContainerAccessor Members#region IContainerAccessor Members

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
        
/// Returns the Unity container of the application 
        
/// </summary>

        IUnityContainer IContainerAccessor.Container
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
return Container;
            }

        }


        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
Application Events#region Application Events

        
protected void Application_Start(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            BuildContainer();
        }


        
protected void Session_Start(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{

        }


        
protected void Application_BeginRequest(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{

        }


        
protected void Application_AuthenticateRequest(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{

        }


        
protected void Application_Error(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{

        }


        
protected void Session_End(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{

        }


        
protected void Application_End(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            CleanUp();
        }

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
Methods#region Methods

        
private static void BuildContainer()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            UnityContainerConfig config 
= new UnityContainerConfig();
            Container 
= config.GetIUnityContainer();
        }

        
private static void CleanUp()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{

            
if (Container != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{

                Container.Dispose();

            }


        }


        
#endregion

    }

}

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

ContractedBlock.gifExpandedBlockStart.gifBasePage
namespace 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的泛型基类。

ContractedBlock.gifExpandedBlockStart.gifBaseUserControl
namespace 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控件上,具体代码如下:

ContractedBlock.gifExpandedBlockStart.gifCode
namespace 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

ContractedBlock.gifExpandedBlockStart.gifCode
namespace 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标记的方法,如下

ContractedBlock.gifExpandedBlockStart.gifCode
[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中。如下

ContractedBlock.gifExpandedBlockStart.gifCode
<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

相关文章:

Matlab与线性代数 -- 稀疏矩阵的创建

本文详细介绍了在Matlab中创建稀疏矩阵的三种方法。

uva 10491 Cows and Cars

https://vjudge.net/problem/UVA-10491 题意&#xff1a; a头牛&#xff0c;b辆车&#xff0c;每扇门后面都有一头牛或一辆车 开始选手选择一扇门 然后主持人打开c扇有牛的门&#xff08;选中的除外&#xff09; 然后选手换一扇门 问最后选手选的门后面是车的概率 开始选牛的概…

ssh免密码登录的原理

工作第一天&#xff0c;就需要登录各种服务器&#xff0c;免密码登录无疑能大大的提高工作效率。以前只知道配置&#xff0c;今天了解了下原理。 免密码登录原理 图解&#xff0c;server A免登录到server B: 1.在A上生成公钥私钥。 2.将公钥拷贝给server B&#xff0c;要重命…

mysql-cluster 安装配置

mysql-cluster免编译包下载&#xff1a;https://dev.mysql.com/downloads/file/?id469881 新版本支持只把索引和用到的数据加载到内存&#xff0c;而不是老版本的整个数据库都得加到内存中wget https://cdn.mysql.com//Downloads/MySQL-Cluster-7.5/mysql-cluster-gpl-7.5.6-l…

ExtJs学习笔记(5)_Ajax示例

ExtJs对于Ajax的使用非常简单&#xff0c;看下面的代码: 1.Html页&#xff1a; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns"http://www.w3.o…

Matlab与线性代数 -- 稀疏矩阵的图形显示

本文详细说明了Matlab中稀疏矩阵可视化的过程。

浏览器及时感知服务端数据变化的方式

需求 在公司&#xff0c;有一个需求&#xff0c;是浏览器实时获取服务端数据变化&#xff0c;然后根据变化做相应的动作。需求场景如下&#xff1a;手机端扫描二维码&#xff0c;然后获取待取件订单列表&#xff0c;点击取件&#xff0c;进行取件&#xff0c;同时远端打印机打…

拥抱Node.js 8.0,N-API入门极简例子

本文摘录自《Nodejs学习笔记》&#xff0c;更多章节及更新&#xff0c;请访问 github主页地址。欢迎加群交流&#xff0c;群号 197339705。 N-API简介 Node.js 8.0 在2017年6月份发布&#xff0c;升级的特性中&#xff0c;包含了N-API。编写过或者使用过 node扩展的同学&#x…

什么是标记符控制的分水岭算法

本文首先指出传统分水岭算法的不足&#xff0c;然后介绍了标记符控制的分水岭算法&#xff0c;最后通过实例演示了该算法在图像分割中的应用。该微信图文由安晟提供。

.NE 后退刷新验证码

Response.Buffer true; Response.Expires -1; Response.ExpiresAbsolute DateTime.Now.AddDays(-1); Response.Expires0; Response.CacheControl "no-cache"; 转载于:https://www.cnblogs.com/lmjob/archive/2008/09/01/128096…

intellij打开工程在每个java文件上有个红色的无效符的解决办法

说明该类不是可编译文件。在project Structure中&#xff08;快捷键ctrlaltshifts&#xff09;选Modules将你带红圈的文件添加上&#xff0c;将你带红圈的文件夹设为Sources。一般是src文件夹&#xff0c;点Sources文件夹&#xff0c;然后点击OK。设置为可编译文件再去工程中看…

[zt] petshop4.0 详解之三

三、PetShop数据访问层之消息处理在进行系统设计时&#xff0c;除了对安全、事务等问题给与足够的重视外&#xff0c;性能也是一个不可避免的问题所在&#xff0c;尤其是一个B/S结构的软件系统&#xff0c;必须充分地考虑访问量、数据流量、服务器负荷的问题。解决性能的瓶颈&a…

windows下Bullet 2.82编译安装(Bullet Physics开发环境配置)

平台&#xff1a;Win7&#xff0c;VS2010 1. Bullet库的组织 下图是Bullet_User_Manual中的截图&#xff1a; 从中可见&#xff0c;Bullet的LinearMath&#xff08;线性数学模块&#xff09;&#xff0c;其上是BulletCollision&#xff08;碰撞检测模块&#xff09;&#xff0c…

Matlab与线性代数 -- 寻找矩阵的非零元素

本微信图文详细介绍了Matlab中find函数的用法。

java重新回顾

很不幸&#xff0c;自己的移动硬盘坏掉了&#xff0c;之前自己所做的学习笔记都没了&#xff0c;大概有300多篇&#xff0c;是大学学习java的时候整理复习的&#xff0c;这样的损失是巨大的&#xff0c;这将花费我更多的时间重新去整理&#xff0c;但是事实已经是这样的了。 基…

BestCoder 1st Anniversary ($) 1002.Hidden String

Hidden String Accepts: 437 Submissions: 2174 Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 262144/262144 K (Java/Others)问题描写叙述今天是BestCoder一周年纪念日. 比赛管理员Soda有一个长度为n的字符串s. 他想要知道是否能找到s的三个互不相交的子串s[l1..r1],…

动态生成GridView时,加入DataKeyNames属性,回调时出错解决方法

早上看到有位同学问关于自动生成GridVie并且添加DataKeyNames属性后 回调页面时&#xff0c;出现错误异常.下面是我实现的方法。注意一点。就是数据绑定的时间。 要是先绑定&#xff0c;再添加到div1中&#xff0c;回调页面时&#xff0c;就会出错。 页面代码&#xff1a; <…

如何制作风格迁移图?

本微信图文介绍了实现风格迁移图的基本原理并在此基础上制作了效果展示图。

leetcode--链表的设计--python

leetcode--链表的设计--python题目题目详情示例提示解题代码代码运行结果体会题目 设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性&#xff1a;val 和 next。val 是当前节点的值&#xff0c;next 是指向下一个节点的指针/引用。如果要使用双向…

从空间数据库中删除所有拓扑对象

/// <summary> /// //从空间数据库中删除所有拓扑对象 /// </summary> /// <returns></returns> public bool DeleteALLTopolgyFromGISDB() { bool rbc true; try { …

Altium Desgner软件,PCB设计中铺铜的作用

PS原文出自http://mp.weixin.qq.com/s/5mLNXzCDm1hGOXiKNE8Ddg 问1:为何要铺铜&#xff1f; 答&#xff1a;一般铺铜有几个方面原因。 &#xff11;、EMC.对于大面积的地或电源铺铜&#xff0c;会起到屏蔽作用&#xff0c;有些特殊地&#xff0c;如PGND起到防护作用。&#xff…

如何利用自组织竞争网络进行患者癌症发病预测

如何利用自组织竞争网络进行患者癌症发病预测 数据下载&#xff1a; http://download.csdn.net/detail/lsgo_myp/9711473

leetcode--反转链表--python

文章目录题目题目详情示例提示解题代码代码运行结果体会题目 题目详情 反转一个单链表。 示例 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL提示 你可以迭代或递归地反转链表。你能否用两种方法解决这道题&#xff1f; 解题代码 …

非递归一次性加载分类数据到TreeViw

不是经常用,发现再次用到时又要再写一遍,这次花点时间记录一下 代码:------------------------------------- private void InitView() { DataView dv CommodityClassBLL.Query().Tables[0].DefaultView; if (dv.Count > 1) { dv.Sort …

什么是SESSION?(二)

本篇图文讨论了SESSION多服务器共享问题以及SESSION操作的效率问题。本篇微信图文由钟锦提供。

leetcode--两数之和--python

文章目录题目题目详情示例解题代码代码运行结果体会题目 题目详情 给定一个整数数组 nums 和一个目标值 target&#xff0c;请你在该数组中找出和为目标值的那 两个 整数&#xff0c;并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;你不能重复…

关于 OpenIdConnect 认证启用 HTTPS 回调 RedirectUri 不生效问题

在搭建 IdentityServer 服务端后&#xff0c;我们尝试使用了 OIDC(OpenID Connect) 的中间件来代替了原先的 Session 系统认证方式&#xff0c;起初采用的是 HTTP 协议&#xff0c;一切都没有什么问题&#xff0c;最近启用全站 HTTPS 后&#xff0c;发现登陆会跳转到 HTTP的页面…

C#中使用GUID

GUID&#xff08;全局统一标识符&#xff09;是指在一台机器上生成的数字&#xff0c;它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成GUID的API。生成算法很有意思&#xff0c;用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。GUID的唯一缺陷在于生…

Matlab与线性代数 -- 对角矩阵

本微信图文详细介绍了Matlab中diag()函数的应用。

leetcode--对称二叉树--python

文章目录题目题目详情示例说明解题代码代码运行结果体会题目 题目详情 给定一个二叉树&#xff0c;检查它是否是镜像对称的。 示例 例如&#xff0c;二叉树 [1,2,2,3,4,4,3] 是对称的。 1/ \2 2/ \ / \ 3 4 4 3但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的: 1…