Categories

Links

nhibernate 将实作hiberante 3.x

看图,算得上是一个好消息吧。看 ccboy 最近的blog 有感,先上来冒个泡。

[2006-04-06 22:07:30 | Author:jiangjianxiao ] [] 8 comments

spring.net validation framework

这部分尚不见文档,所以在这里提几句,以便大家对其有个了解

validation framework(以下简称vf) 极大的依赖Spring.Expression ,关于Spring.Expression的简单介绍,可参见我在评测网的另一个贴子 http://bbs.dotnettools.org/NewsDetail.asp?id=5238 . 这里所说的基本上是我个人的理解,因此有些地方可能不对。

vf 特点
①与经典的asp.net验证框架不同,vf 在页面上并没有验证逻辑,在页面上通常只有validationSummary和validationError控件,显示验证的结果,验证逻辑存在于ioc容器中。验证逻辑是可重用的,通常被部署为singleton
②验证 是一个整体的动作,即一次验证活动可以有一个或多个验证操作,因此,vf 通常用一个ValidatorGroup 来表达一次验证活动。一个组的可以通过ref(ValidatorReference来引用另一个组中的验证器
③ 在spring.net web framework中,验证活动是手动调用的,通过Page.Validate(object validationContext,params IValidator[] validators)来进行。而经典的asp.net 验证是自动的,如果要跳过验证逻辑,必须设置causesvalidation属性为false

④对国际化支持相当完善。

 


每个validator通常都暴露test,when两个attribute,test是validator需要的表达式,when是是否执行该validator的表达式
每个validator可以有一批IValidationAction的实现列表,这个列表是表明验证后需要执行的活动.有两个预定义的活动ErrorMessageAction,ExpressionAction

在vf中,表达式可以使用validatecontext和一个parameters dictionary,vaidatecontext通常是要验证的对象,它是spring.net web framework Page.Validate方法传递的第一个参数。这个参数通常是domain object ,如一个用户注册页面,通常就是User 对象,而一个订单录入页面,通常就是Order对象了,如果没有对应的domain object,你可以创建一个或是通过page对象来引用页面上的控件。parameters在web framework中,由Page类创建并传入,下面是Page.createValidatorParameters的代码
 private IDictionary CreateValidatorParameters()
        {
            IDictionary parameters = new ListDictionary();
            parameters["page"] = this;
            parameters["session"] = this.Session;
            parameters["application"] = this.Application;
            parameters["request"] = this.Request;
            parameters["response"] = this.Response;
            parameters["context"] = this.Context;

            return parameters;
        }
你可以在表达式中使用
#page
#session
#application
#request
#response
#context
来引用这些对象
比方说一个登录页面,你可以显式的构造一个LoginInfo对象,如
public class LoginInfo
{
 public String UserName;
 public String Password;
}
在具体的登录代码中使用这个对象
  protected void cmdLogin_Click(object sender, EventArgs e)
    {
        LoginInfo info=new LoginInfo(txtUserName.Text,txtPassword.Text);

      if (  Page.Validate(info,loginValidator))
      {
  //验证通过
      }
       
    }

对于登录活动,这里显然需要有以下验证过程
用户名必须输入,口令必须输入
如果口令输入,则口令必须大于6位
我们来描述以下如何完成这个过程


<v:group id="loginValidator">
 <v:required id="userNameValidator" test="UserName">
  <v:message id="error.required" providers="usernameErrors, validationSummary">
   <v:param value="#page.GetMessage('username')"/>
  </v:message>
 </v:required>
 <v:required id="passwordValidator" test="Password">
  <v:message id="error.required" providers="passwordErrors, validationSummary">
   <v:param value="#page.GetMessage('password')"/>
  </v:message>
 </v:required>
<v:condition id="passwordLengthValidator" test="#page.wc2.txtPassword.Text.Length>6" when="#page.wc2.txtPassword.Text.Length>0">
     <v:message id="error.length" providers="passwordErrors, validationSummary">
      <v:param value="#page.GetMessage('password')"/>
      <v:param value="6"/>
     </v:message>
    </v:condition>
</v:group>


这里定义一个ValidatorGroup loginValidator ,它包括两个validator,第一个是UserName必须输入,第二个是Password必须输入。如果第一个validator没通过,则显示message。message 的id是个资源字符串id,vf通过GetMessage获取这个资源字符串id对应的本地化字符串,它有可选的多个参数。这里error.required 在全局资源中定义为{0} 必须输入,下面的param 指示从调用GetMessage方法获取username的本地化字符串,最终它会显示 用户名 必须输入.password的验证同理。

这里,需要提一下param 的value总是会被转换称一个IExpression,所以这里可以使用表达式的所有功能

message的providers attributes 是很有意思的东西,他说明这个message给那个validationError控件用,如
<asp:TextBox ID="txtUserName" runat="server" /><spring:ValidationError ID="ValidationError1" Provider="usernameErrors" runat="server" />
大家注意到ValidationError1的Provider attribute 定义为usernameErrors,显然,一个ValidationError可以使用多个message,只要其在message的providers列表中

上面已经说了,在具体的asp.net 页面中,只使用ValidationSummary和ValidationError控件。这两个控件的配置也很有意思
下面的例子是ioc中的配置
<object id="Spring.Web.UI.Controls.ValidationError" abstract="true">
    <property name="Renderer">
     <object type="Spring.Web.Validation.IconValidationErrorsRenderer, Spring.Web">
      <property name="IconSrc" value="validation-error.gif"/>
     </object>
    </property>
   </object>
   <object id="Spring.Web.UI.Controls.ValidationSummary" abstract="true">
    <property name="Renderer">
     <object type="Spring.Web.Validation.DivValidationErrorsRenderer, Spring.Web">
      <property name="CssClass" value="validationError"/>
     </object>
    </property>
   </object>

由于spring.net web framework 的Page类会对页面中的每个control调用ConfigureObject,因此,页面中的validationError,summaryError都会被配置。

要使用vf,首先你需要声明xml ns,如
<objects xmlns="http://www.springframework.net" xmlns:v="http://www.springframework.net/validation">
vf的配置解析Spring.Validation.ValidationConfigParser是个很好的例子,如何将配置简化而不使用固有的ioc xml配置描述。

 


 

[2006-02-19 22:21:14 | Author:jiangjianxiao ] [] 1 comments

spring.net web 在asp.net 2.0 (未完成)

ms 的兼容性处理从来没有这样差过,我想一个复杂,结构处理不好的vs 2003 web application ,当升级到vs 2005的website时,错误百出。就像从vb6升级到vb.net 。

这个结构不好意思指一个web application充斥着class,usercontrol,aspx页面。因此通常建议将此类项目分离到多个项目中,比方说class 为一个项目,usercontrol为一个项目,aspx页面一个项目。这样迁移会好些。

面对asp.net 2.0的website类型,对 spring.net webframework 显然是个很大的冲击。asp.net 2.0的项目生成不确定的dll名,如果你需要在context中注册一个usercontrol ,如WebUserControl,asmmeblyname ,要知道,assemblyname可能会变化

<object  type="WebUserControl,App_Web_4oiomlv1" abstract="true">
   </object>
   或许你以为这个usercontrol在当前website中,省略assemblyname 也可以运行,那你就错了,这个假定未必能成立。

hoho,其实这是对spring.web 中如何注册user control 的一个典型误用,如果你声明了type attribute,则容器必定会创建这个type(用类似GetType(string)之类的方法,这显然不是你想要的abstract模式

替代的用法是用id或name attribute,如

<object id="WebUserControl" abstract="true">

<property name="Message" value="hello, spring.web"/>

</object>

这里id必须使用user control的basetype全名

当然,你用可以使用控件的id,但从spring.web page的实现代码看,当你的usercontrol在一个容器控件中时,这不是你所期望的

spring.web Page 类的InjectDependenciesRecursive方法显示spring.web 是如何对一个usercontrol进行依赖注入的。这里,我们可以看到spring.net ioc的ConfigureObject的灵活性。其它的ioc容器并不具备这样的能力

好在全局资源总是会编译成App_GlobalResources.dll ,这样spring.net web的ResourceSetMessageSource总算能够使用

<object id="messageSource" type="Spring.Context.Support.ResourceSetMessageSource, Spring.Core">
    <property name="ResourceManagers">
     <list>
      <value>Resources.Strings, App_GlobalResources</value>
     </list>
    </property>
    <property name="UseCodeAsDefaultMessage" value="true"/>
   </object>

 

在asp.net 2.0中,最大的冲击是spring.web的databind模式,因为asp.net 2.0将页面编译为一个partial class,用户无法触及,就是新的web application 项目类型,也是如此,因为这个页面总是会被设计器重新生成

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.42
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
因此原有的在asp.net控件上施加DataBind attribute的做法就不能沿袭使用,好在spring.web并不算是个定稿的项目,这是在spring forum上的spring.web 主要开发者的新的DataBind的思路

No, you didn't get it wrong 

I'm actually working on it as we speak and porting SpringAir to ASP.NET 2.0 in the process. So far I have master pages and localization working in both 1.1 and 2.0, and will start working on the data binding support tomorrow.

I will probably mark DataBindingAttribute as obsolete and replace it with CreateBinding method that takes source and target binding expressions as parameters. I will also add InitializeBindings method, which you should override in order to define the bindings.

To give you an example, instead of this:

Code:

[DataBinding("Text", "Name")]
protected TextBox txtName;


you will do something like this:

Code:

protected override void InitializeBindings()
{
    CreateBinding("txtName.Text", "Name");
    ... add other bindings
}


This will actually be a recommended way of doing it in both 1.1 and 2.0, as it gives you more freedom and flexibility when defining bindings. For example, it allows you to do something like this as well:

Code:

    CreateBinding("Request['CustomerID']", "CustomerID");
    CreateBinding("Session.Items['UserProfile']", "UserProfile");


I'm hoping to have everything working by the end of this week, so please be patient just a bit longer.

Regards,

Aleks

 

[2006-02-18 11:19:46 | Author:jiangjianxiao ] [] 3 comments

梦幻语言- D

D语言是这么多年来我首次一见就疯狂喜欢上的语言。感谢 uFramer(焦冶) 翻译的中文文档给了我们快速了解D语言的途径。

quote:

这是一种设计成C++语言继任者的通用语言,提供了很多优良特性,例如按合约设计(Desing by contract)、垃圾回收(garbage collection)、高阶数组(first class arrays)、闭包(closures)、模版(templates)等。

 

目前,d语言缺少像java或是.net 丰富的类库,社区也不够活跃,个人感觉这只是了解的人不多而已。就语言特性而言,应该是相当丰富的,由于开源社区有mono和gnu classpath,加之d编译器已经有gnu 版本,前途是不可估量的。Shawn Liu 也对swt 的移植说明了java项目移植的可能性  

链接

安装及使用

下载dmd.zip/dmc.zip ,解压到磁盘目录,把dmd\bin和dm\bin追加到环境变量path中即可

使用dmd 编译d源代码,如

1. hello.d

void main(){
 printf("hello, world!");
}

2. dmd hello.d

3. hello

 

 

[2006-02-15 08:39:22 | Author:jiangjianxiao ] [] 2 comments

推荐一个新的.NET AOP框架-Sophus Beta

SpiderMan 从评测网的报道,一个.NET的AOP 框架-Sophus 已经Beta准备发布了。
Quote
这个框架我们公司R&D部门自己开发的。一开始我们使用了Aspect#在我们的开发中,后来由于license和性能等的一些问题,使我们产生了自己写一个AOP的想法。Sophus最大的特点就是速度非常快,这里有一些何Aspect#对比测试的结果:

 

注意: dotnettools 评测网已经改用utf-8 编码,如果您浏览器白屏,请将浏览器的编码切换到自动选择或手动选择utf-8,抱歉给您造成不变

[2006-02-14 09:20:54 | Author:jiangjianxiao ] [] 2 comments

Total 91 Display 51 of 55
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Powered by Google App Engine