zoukankan      html  css  js  c++  java
  • 定义ExpressionBuilder减少服务器端的代码耦合度

    在System.Web.Compilation下默认提供了三个常用的ExpressionBuilder,比如在UI上快速访问AppSettings可以这么写:

    1 <%= ConfigurationManager.AppSettings["IsDebug"] %>
    2 <%$ appSettings:IsDebug %>

    %$ appSettings:IsDebug %>实际上调用了AppSettingsExpressionBuilder,这一层的转换到调用由ASP.NET页面的动态编译器负责(其实到真正动态执行某个页面时所加载的类型并不是我们编写代码时的那个类型,而是被动态编译后的派生类型)。再比如我们可以使用ConnectionStringsExpressionBuilder快速访问数据库连接字符(在ASP.NET的默认Web.config下分别注册了appSettings、connectionStrings和resources):

    <asp:SqlDataSource ID="sqlDataSource1" runat="server" ConnectionString="<%$ connectionStrings:mainDB%>" />

    可以看出使用这类ExpressionBuilder的目的是帮助我们将那些完全和业务逻辑无关的代码放置在ASPX页面中,比如使用TextBox显示当前时间:

    <asp:TextBox ID="tbDtNow" runat="server" Text="<%=DateTime.Now%>" />

    执行结果:

    <input name="tbDtNow" type="text" value="&lt;%=DateTime.Now%>" id="tbDtNow" />

    上面输出的并不是我们所想要的结果,当然完全可以使用非服务器端控件来达到相同的目的:

    <input type="text" id="tbDtNow" value="<%=DateTime.Now%>" />

    许多情况下我们必须使用服务器端控件,而这些服务器端控件的某些和UI相关的资源需要我们动态构造,比如ImageButton、TreeView。它们通常需要指定图片(ImageUrl、ExpandImageUrl…)。

    <asp:ImageButton ID="btnSearch" runat="server" ImageUrl="searchWebHS.png" OnClick="searchWebHS_Click" />
    根据皮肤的名称不同,可能ImageUrl会被动态修改,比如~/Skins/Classic/searchWebHS.png。使用服务器端代码可以轻易完成,但是预编译aspx页面却没有表达式可以替代。
    服务器端:
    this.btnSearch.ImageUrl = ResolveClientUrl(String.Format("~/Skins/{0}/searchWebHS.png", this.SkinID));

    ASPX:

    ImageUrl="Skins/<%=SkinID%>/searchWebHS.png"
    ImageUrl=’<%="Skins/" + SkinID + "/searchWebHS.png"%>’

    以上代码都无法被动态解析正确。如果使用服务器端代码方式对于以后和UI相关的修改就需要每次编译。所以相对较好的解决方式就是创建一个自定义的ExpressionBuilder。比如上面关于动态构造ImageUrl可以直接返回表达式并动态计算执行。下面演示如何编写一个自定义的ExpressionBuilder(关于ExpressionBuilder的更详细介绍建议查阅MSDN):

     1 [ExpressionPrefix("code")]
     2 public class RuntimeCodeExpressionBuilder : ExpressionBuilder
     3 {
     4     public RuntimeCodeExpressionBuilder() { }
     5  
     6     public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, Object parsedData, ExpressionBuilderContext context)
     7     {
     8         return new CodeSnippetExpression(entry.Expression);
     9     }
    10  
    11     public override Boolean SupportsEvaluate
    12     {
    13         get { return true; }
    14     }
    15 }

    GetCodeExpression返回需要动态计算的代码表达式,而CodeSnippetExpression表示原意代码段(关于CodeExpression和CodeObject可以查阅和CodeDom相关的文档)。RuntimeCodeExpressionBuilder的类Attribute定义了使用的前缀表达式,如果想要自定义Design时的编辑器可以声明ExpressionEditor。重新修改ImageButton的ImageUrl:

    <asp:ImageButton ID="btnSearch" runat="server" ImageUrl=’<%$ code:ResolveClientUrl("~/Skins/") + SkinID + "/searchWebHS.png"%>’ OnClick="searchWebHS_Click" />

    同时需要在Web.config中注册新的ExpressionBuilder:

    system.web ->compilation -> expressionBuilders
    <expressionBuilders>
      <add expressionPrefix="code" type="ExpressionBuilderDemo1.RuntimeCodeExpressionBuilder,ExpressionBuilderDemo1" />
    </expressionBuilders>
  • 相关阅读:
    spring-boot 在启动运行脚本中执行修改表结构,执行前校验表结构是否符合,如果不符合就修改
    Ehcache flush() 源码阅读笔记
    关于超时的实现---利用Timer
    java 基础笔记--Map
    spring-boot+mybatis+ehcache实现快速查询
    笔记---html输入限制
    spring boot thymeleaf模板url上的参数传递
    xcode 8   去除无用打印信息
    项目整理 (一)
    FMDB最简单的教程-3 清空数据表并将自增字段清零
  • 原文地址:https://www.cnblogs.com/junchu25/p/2631416.html
Copyright © 2011-2022 走看看