最近两三个月,我在学习 Java。为了在实践中快速进步,我决定把 .NET 中目前应用最广泛的一个 Ajax 类库 Ajax.NET 翻译到 Java 中,目的主要是熟悉 Java 的语法和类库(尤其是 Web 方面 Servlet 相关的知识)。到今天有了一个阶段性的成果,我已经可以像 .NET 中作的那样在脚本中直接调用服务端的简单方法了:
package ajaxnet4j.demo;
public class Test {
@ajaxnet4j.AjaxMethod
public String HelloWorld(String person) {
return "Hello, " + person;
}
}<script type="text/javascript">
function test() {
var name = document.getElementById("txtPerson").value;
res = ajaxnet4j.demo.Test.HelloWorld(name);
if (res.error == null) {
alert(res.value);
} else {
alert(res.error.Type + ": " + res.error.Message);
}
}
</script>
翻译的过程,接触了 Servlet (相当于 IHttpHandler),Reflect(相当于 Reflection 反射发出),Java 1.5 Annotation(相当于 Attribute)等等,对 C# 和 Java 相比的语法差异,.NET 和 Java 相比的类库映射有了不少认识,对了继续深入的学习 Java 算是一个不错的起点。当然对于 Ajax.NET 的内部构造也了然于心了。收获颇丰。
当然,受制于 Ajax.NET 的 Licence,我还没有办法发布 ajaxnet4j (无论是源码,或是 jar 包),正在向原作者请求,不知道他会不会答应。哎,有可能死在摇篮中啊,那就是遗憾了。
下一个话题我们来看 ASP.NET 2.0 中新增的 Profile 功能。这和我们要谈的 BuildProvider 有什么关系么?
.NET Framework SDK 的文档中有这样一段话,引起了我的兴趣。位于 System.Web.Profile.ProfileBase 类的首页上:
在启动启用了用户配置文件的应用程序时,ASP.NET 会创建一个类型为 ProfileCommon 的新类,该类从 ProfileBase 类继承。强类型访问器被添加到 profile 配置节中为每个属性定义的 ProfileCommon 类中。ProfileCommon 类的强类型访问器调用 ProfileBase 基类的 GetPropertyValue 和 SetPropertyValue 方法,分别用于配置文件属性值的检索和设置。ProfileCommon 类的一个实例被设置为 ASP.NET 应用程序的 Profile 属性的值。
为了启用 Profile 机制,我们需要在 web.config 中进行必要的配置。比如:
<xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<connectionStrings>
<add name="TestDB"
connectionString="........"
providerName="System.Data.SqlClient" />
</connectionStrings>
<system.web>
<profile defaultProvider="TestProfileSqlProvider">
<providers>
<clear />
<add name="TestProfileSqlProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="TestDB"
applicationName="Test" />
</providers>
<properties>
<add name="PreferredLang" defaultValue="zh-CN" />
<add name="PreferredTheme" defaultValue="Blue" />
<add name="RecordsPerPage" defaultValue="20" type="System.Int32" />
</properties>
</profile>
</system.web>
</configuration>
上面的 Profile 配置,数据将被存储在 TestDB 这个 ConnectionString 所代表的那个数据库中。Profile 中添加了三个 properties:一个是 PreferredLang,代表用户最喜欢的界面语言;一个是 PreferredTheme,代表用户最喜欢的 ASP.NET 主题;一个是 RecordsPerPage,表示如果启用分页,每页显示的记录条数。注意最后一个指定了类型 int。
下面按照我说的步骤做:找一个 *.aspx.cs 文件(如果你没有用 Code-Behind,则直接在 *.aspx 的 script runat="server" 块中),比如在它的 Page_Load 方法中,输入 Profile,把鼠标放上去,你看到了什么?
比如当前这个画面的类名叫 Abc,你通过智能感知看到的应该是 “ProfileCommon Abc.Profile”,表示这个 Profile 类型是 ProfileCommon,是当前类的一个属性。
如果你继续敲一个点,你会发现这个类具有 PreferredLang (string 类型),PreferredTheme (string 类型),RecordsPerPage (int 类型)。恰好和你在 web.config 中的配置是一致的。
如果你有兴趣,可以在 Profile.PreferredLang 的后半部分,右击,“Go To Definition”,你会看到这个 ProfileCommon 的代码,当然这些代码也是自动生成的。这个 ProfileCommon 类从 ProfileBase 类继承,在基类基础上根据 web.config 的配置,添加了三个属性。
看到这里,最开头那段话的意义就明了了。
但我这篇的重点,并不在于 ProfileCommon 类本身,因为有了 DataSet 的基础,这个 ProfileCommon 也比较容易理解。我想请各位读者关注一下这个 Abc.Profile 属性。
无论是使用单文件 aspx 还是 Code-Behind 机制的 aspx/aspx.cs 双文件,我们都没有显式声明过、一个名称叫做 Profile、类型为 ProfileCommon 的属性。而且在页面的基类 Page 中,更是找不到踪影。那么这个属性是从哪儿来的?
这也是 ASP.NET 2.0 中内置的一个 BuildProvider 的作用。下一篇以 BuildProvider 的视角重新审视 ASP.NET 2.0 中的 Code-Behind 机制。(待续...)
昨天知道了公司里年度调薪的结果,公司食言了,连他们自己许诺过的最低数字都没有达到,这次是彻底失望了,因为公司已经没有什么信誉可言了。
言归正传,上一篇中我给大家介绍了 ASP.NET 2.0 中新的 DataSet 设计器,并告诉大家:在 ASP.NET 2.0 中,用 DataSet 设计器设计的那些图形,在编译开始前,将被 DataSet BuildProvider 自动转换为相应的代码。
关于那些自动生成的代码,有下面几点提醒大家注意:
1) TableAdapter 类是 partial 的:意味着我们可以给这些 TableAdapters 外接一些方法等成员,我们可以通过外接把那些通过拖曳图形无法完成的代码、接续到特定的 TableAdapter 类中。
2) TableAdapter 类中使用的那些 Connection, Command, DataAdapter 等等的类型,会根据所访问数据库的不同(准确说是所使用的 .NET Data Provider 的不同)而变化。如果 web.config 中标明某个 ConnectionString 是使用 System.Data.OleDb,那么下次 DataSet 设计器存盘,会自动变成 OleDbConnection, OleDbCommand, ... 这些类型。
BuildProvider 是 ASP.NET 2.0 中新推出的功能,那么 Visual Studio .NET 2002/2003 中的 DataSet 设计器,是如何自动生成代码的?细心人注意过这一点,在 VS 2002/2003 的属性面板中,可以看到有一个“自定义工具”的,里面写着“MSDataSetGenerator”,类似的还有“CrystalDecisions.VSShell.CodeGen.ReportCodeGenerator”(水晶报表的 *.rpt 文件)。VS 2002/2003 使用的是 CodeGenerator 来自动生成代码。
其实,如果打开 Visual C# 2005 Express Edition 或者 Visual Basic .NET 2005 Express Edition,同样创建一个 DataSet,你会发现那里仍然是“Custom Tool”和“MSDataSetGenerator”,仍然是通过 CodeGenerator 自动生成代码的。
看来 BuildProvider 功能仅限于 ASP.NET 的项目,不适用于 Windows Forms 或者类库项目。
从这篇开始,开始陆续向大家介绍 ASP.NET 2.0 中一个新功能,在国内社区还很少有人论及,我就献丑了。
我第一次注意到这个新功能,是因为尝试使用 Visual Web Developer 2005 Express Edition 中的、新的 DataSet 设计器。这个 DataSet 设计器,和 Visual Studio .NET 2003 中的相比,有了很大的变化,最大的变化应该说是 TableAdapter。
新的 DataSet 设计器中,每个 DataTable 可以在它下方附带一个 TableAdapter。这个 TableAdapter 可以有若干个 Query。SELECT rows (获取一个 DataTable 的)类型的 Query 所返回的记录集,应该和它上方的 DataTable 定义的列相对应。其他类型的 Query,包括 SELECT scalar(只取第一行第一列的)以及 UPDATE, INSERT, DELETE 等,也可以被包含在这个 TableAdapter 中。
另外,TableAdapter 也可以单独存在(不依赖于 DataTable),不过如果是单独存在,那它就只能包含 SELECT scalar / UPDATE / INSERT / DELETE 等 Query,不能包含 SELECT rows 类型的 Query。
在这些 TableAdapters 或者说在新的 DataSet 设计器的帮助下,只要你愿意,你不需要再另外书写访问数据库(DAL)的代码(虽然有人会担心效率、耦合等等)。因为这些 TableAdapter 可以完成绝大多数常见的 DAL 操作。
接受了 TableAdapter 模式后,很多人(包括我)都会产生几个问题:TableAdapter 和 DataAdapter 有什么联系么?TableAdapter 是 .NET Framework 2.0 中新推出的一种类型?后一个问题,很容易就可以回答,因为 .NET Framework 2.0 SDK 的类库文档中,找不到任何叫做 TableAdapter 或者包含 TableAdapter 字样的类型。
很多细心人知道,在 Visual Studio .NET 2003 的 DataSet 设计器背后,每一个 *.xsd 文件背后都有一个 *.xsx 文件和一个 *.cs 文件(如果你用别的编程语言,扩展名可能不同)。前者只存储了设计器中每个图形的坐标和大小,它纯粹是为 DataSet 设计器服务的,可以在下次打开设计器时,恢复原来各个图形的位置。后者却包含了设计器中那些代表 DataTable 的图形所产生的代码。熟悉 VS.NET 2003 DataSet 的朋友,或许已经研究过这些冗长而枯燥的代码了。
可是在 Visual Web Developer 2005 Express Edition 的 DataSet 设计器背后,却只有一个 *.xss 文件,这个文件和 VS 2003 中的 *.xsx 文件一样,只记载了各个图形的坐标和大小。那些 *.cs 代码去哪儿了?
其实有一个简单的方法,可以查看到这些代码,那就是大家熟悉的“Go To Definition”菜单命令。
或许你已经熟悉了下面的事情:如果 DataSet 的文件名叫做 AbcDS.xsd,其中有一个 DataTable 叫 Users,则实际上:
1) DataSet 的类名就叫 AbcDS,
2) 那个 DataTable 就是 AbcDS.UsersDataTable;
3) 这个 DataTable 上附带的那个 TableAdapter 默认叫做 UsersDataTableAdapter,不过它处在一个叫做 AbcDSTableAdapters 的命名空间中,全名也就是 AbcDSTableAdapters.UsersDataTableAdapter。
任意找一个 *.cs 文件,我们输入 AbcDS,在智能感知的帮助下,我们可以看到 AbcDS.* 和 AbcDSTableAdapters.*。我们继续把类名书写完全后,右击,Go To Definition。看到这些代码了吧?
我在这个地方停一下,大家先琢磨琢磨那些自动产生的代码吧。这些代码都是 ASP.NET 2.0 中的内置的 DataSet BuildProvider 动态产生的。(待续...)
我一直关注着 NDoc,等待它的最新版本支持 .NET 2.0 的新功能,也期待有机会完成新的 NDoc 中文版。
刚刚在网络中得到一条坏消息,虽然还不太确信,但仍然转给大家:
Todd Brooks, posted at 26 Jul 2006, 11:53 PM UTC:
Looks like NDoc 2.0 is dead. I received this email from Kevin Downs (developer of NDoc) this morning:
"
I have decided to discontinue work on NDoc 2.0 and no longer participate in any open-source development work.
The development and release of NDoc 1.3 was a huge amount of work, and by all accounts widely appreciated. Unfortunately, despite the almost ubiquitous use of NDoc, there has been no support for the project from the .Net developer community either financially or by development contributions. Since 1.3 was released, there have been the grand total of eleven donations to the project. In fact, were it not for Oleg Tkachenko’s kind donation of a MS MVP MSDN subscription, I would not even have a copy of VS2005 to work with!
To put this into perspective, if only roughly 1-in-10 of the those who downloaded NDoc had donated the minimum allowable amount of $5 then I could have worked on NDoc 2.0 full-time and it could have been released months ago! Now, I am not suggesting that this should have occurred, or that anyone owes me anything for the work I have done, rather I am trying to demonstrate that if the community values open-source projects then it should do *something* to support them. MS has for years acknowledged community contributions via the MVP program but there is absolutely no support for community projects.
Once ‘Sandcastle’ is released, it is my belief that it will become the de-facto standard and that NDoc will slowly become a stagnant side-water. This will happen regardless of technical considerations, even if Sandcastle were to be less feature-complete. It's just an inevitable result of MS's 'not-invented-here' mentality, one only has to look at Nant and NUnit to see the effects of MS 'competition'.
This is not, however, my only reason for stopping development work - I have a big enough ego to think I could still produce a better product than them :-)
As some of you are aware, there are some in the community who believe that a .Net 2.0 compatible release was theirs by-right and that I should be moving faster – despite the fact that I am but one man working in his spare time...
This came to head in the last week; I have been subjected to an automated mail-bomb attack on both my public mail addresses and the ndoc2 mailing list address. These mails have been extremely offensive and resulted in my ISP temporarily suspending my account because of the traffic volume. This incident has been reported to the local authorities, although I am highly doubtful they will be able to do anything about it.
This has was the ‘last-straw’ and has convinced me that I should withdraw from the community; I’m not prepared to have myself and my family threatened by some lunatic!
Kevin
"
信中所说的
Sandcastle 是微软正在进行的项目,和 NDoc 一样,是文档生成工具。微软用它生成 .NET Framework 的类库文档。据说一开始需要10个多小时才能完成一次生成动作,现在已经优化到30多分钟。已经有测试版本可以下载。