2008来了,悄悄地走近了我们,前几天写了半个草稿,刚整理完毕了,在2008年的第一天,将此贴献出。
读了Terry Li的微软代号为"Volta"的编程工具集预览 ,对Volta产生了好奇感,体验一下。
对Volta的介绍,请查看此网站,本文只体验+翻译其网站上提供的QuickStart 。多余话不说了,开始:
通过8步用Volta建立应用程序
下面的几步帮助你快速地用Volta建立应用程序。一旦你对Volta有了一个较好的理解,你应该根据你的目的和喜好以及约束来调整下面这些步骤。其他的详细信息可参照developer guidance. 注意Volta需要有Vs2008的支持。
第一步:新建Volta项目
Volta的安装程序向VS中配置了VSIP包,该包中添加了几个的Volta的项目类型,当然了,还添加了Volta的编译器和libraries。
在vs2008中,点击File→新建→项目,然后选择在VisualC#下的Volta,然后选择Volta Application,如下图所示:
给项目命名,比如叫"QuickStart",Volta应用程序模板生成了Volta的项目和几个如下的文件:
步骤2:设计用户接口
这个文档中的Volta应用程序把浏览器作为目标,因此UI包括了HTML的元素。
展开 VoltaPage1.cs文件来编辑HTML文件.
初始的HTML 代码如下所示:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Quickstart</title>
<link rel="shortcut icon" href="/favicon.ico"/>
<style type="text/css">
</style>
</head>
<body>
</body>
</html>
我们向该页面中添加一个text输入框(命名为Text1),一个button元素(命名为Button1)(<input type="button" />和<button>均可以),和一个div(命名为Greeting)。通过可视化的设计器直接拖元素到本页面或者手写代码来均可。
注意你可以添加<button>或者<input>元素来向页面上添加一个按钮,在HTML编辑器中前者更为前者更为简单,而在设计器中却使用的是后者。无论使用哪一种,浏览器都以相同的方式呈现这些元素。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Quickstart</title>
<style type="text/css">
</style>
</head>
<body>
<p>
Your name:
</p>
<p>
<input id="Text1" type="text" />
</p>
<p>
<button id="Button1">
Greet
</button>
</p>
<div id="Greeting">
</div>
</body>
</html>
第三步:设计业务逻辑
在这个QuickStart中,一个单独的类就包括了所有的业务逻辑(因为这个非常简单:))
向项目中添加下面这个Greeter类:
namespace Quickstart
{
public class Greeter
{
string helloStr;
public Greeter()
{
helloStr = "Hello";
}
public string Greet(string name)
{
return helloStr + " " + name;
}
}
}
添加完之后,解决方案应该和下面这个屏幕截图相类似了:
第四步:关联DOM和注册事件
当用户按下Greet按钮之后,程序执行Greeter类实例中的Greet方法来响应用户的单击事件:
首先,在VoltaPage1类中添加HTML的DOM元素的变量(如果在的html设计器中你用了<input type="button" />来表示一个按钮的话,此处的Button1变量的类型应该是input)
Input nameElement;
Button button1;
Div greetingElement;
然后定义InitializeComponent()的局部方法,在该方法中关联这些对象和DOM。
然后定义下面的局部方法InitializeComponent(),该方法这些对象和DOM关联起来。GetByID<>()方法提供了访问DOM的元素的方法,比如说按钮(产生事件的元素)和文本域。
partial void InitializeComponent()
{
nameElement = Document.GetById<Input>("Text1");
greetingElement = Document.GetById<Div>("Greeting");
button1 = Document.GetById<Button>("Button1");
public VoltaPage1()
{
InitializeComponent();
var greeter = new Greeter();
button1.Click += delegate
{
var name = nameElement.Value;
};
}
现在就可以高度这个例子的代码了。首先你看VS是在调试状态下的:
然后选择调试用的浏览器。可以选用IE和火狐,这对跨浏览器的调试很有用:
然后在匿名代理的中设计个断点:
按下F5,执行该应用程序。一旦IE呈现出了HTML元素的时候,在文本框中输入一些文字然后按下"Greet"按钮:
VS将会运行到断点处停止。这种体验在调试C#应用程序时是非常明了的。调试时包括了调用的堆栈,本地代码窗口,监视窗口和即时窗口等等一些操作。
第5步:更新显示
应用程序通过更改方法来控制显示的内容,将本地的变量传入一个参数传入方法。匿名代理如下:
button1.Click += delegate
{
var name = nameElement.Value;
greetingElement.InnerText = greeter.Greet(name);
};
到这里,这个应用程序就已经是一个完整的了。要想运行生成的JS代码,你要先将VS的运行方式更改为Release模式:
将运行模式更改为Release之后,按下F5来运行该程序,转到HTML页面即ok了
布署这个应用程序也非常简单,在解决方案管理器中右键该项目,选择Publish,然后选择要将代码输出的目录即可:
第6步:将应用程序重构为多层的应用程序:
到现在为止建立的这个Volta应用程序只是一个单层的应用程序,一切都在客户端的浏览器上运行。
要将该程序转为多层的程序,就要显示地通过设置一个自定义的属性来分层。方法如下:
确保项目属性中的Enable Volta Tiersplitting复选框是处于选中状态下的:
打开Greeter.cs文件,在类上右键,然后选择Refactoer->Tier-split使之在本地运行。该重构就会自动添加一个引用,并将其标识上一个自定义的属性:
using Microsoft.LiveLabs.Volta.MultiTier;
namespace Quickstart
{
[RunAtOrigin()]
public class Greeter
{
private string greeting;
public Greeter()
{
greeting = "Hello";
}
public string Greet(string name)
{
return greeting + " " + name;
}
}
}
现在F5运行之。对其他代码没有进行任何更改,运行方式发生变化如下:应用程序在浏览器端运行,而Greeter这个类在服务器上运行:
你可以在该应用程序的客户端验证一下服务器的请求。在上面服务器的icon上双击,服务器的详细信息页就显示出来。然后将"LOg requests"按钮选中。点击“Greet"按钮来触发一个POST,使POST行为在服务器的日志上能够看到。
第7步:开始异步执行
既然该程序现在以分布式的方式运行,那么Greet()方法异步调用应该更适合。
在Greeter类中,添加一个新的Greet()方法,方法定义如下:
[Async]
public extern void Greet(string name, Callback<string> callback);
然后在HTML页面添加一个新的按钮,添加一个新的button2变量到VoltaPage1类中,并将该变量button2与刚添加的按钮关联起来。设置其事件为调用上面的Greet方法,将用户提供的名字和lambda表达式作为参数传入:
<button id="Button2">
Async Greet</button></p>
Button button2;
button2 = Document.GetById<Button>("Button2");
button2.Click += delegate
{
var name = nameElement.Value;
greeter.Greet(
name,
message => { greetingElement.InnerText = "async: " + message; });
};
然后运行该程序,点击"Async Greet"按钮,现在这个问候的消息就是异步生成并异步更新页面了。(韩现龙:此处的感觉确实比刚才的同步调用要好许多,同步调用的体验非常差,虽然是页面不刷新,但是初次点击时大概需要反应1-2秒的时间,异步调用时就感觉不到反应时间)
第8步:添加End-to-End Profiling(此功能没体验)
一般来说,当建立一个分布式应用程序时,你想在分布的元素之间有一个好的交互。
Volta提供了end-to-end 的特性。为了将程序标记为分层的,你只需简单地将项目属性页中的"Enable Rotunda end-to-end profiling"复选框选中即可。这个设置就保证了应用程序生成表现元素。
然后在Release模式下运行程序。下图记录了运行时的情况:
当结束程序运行(或者关闭浏览器或者在VS中停止),Windows Communication Foundation服务器跟踪就会打开。该查看器读取profiling信息并且提供几种查看方式来表示在运行时发生了什么。例如,下面是以图表的方式显示运行时的数据:
关于使用trace viewer的更深的信息已经可以在线阅读:
- http://msdn2.microsoft.com/en-us/library/aa751795.aspx
- http://msdn2.microsoft.com/en-us/library/aa738749.aspx
[1] 该事例是用C#写的,你也可以用其他的.NET语言来写。
我的事例代码在公司电脑中,等2号上班再给传上来。
这种编程思想毕竟还是处于初生阶段,虽然说它的代码是“延迟加载”,可我在运行该事例时能明显地感觉到初次加载的速度非常慢,可能是加载的东西太多的缘故,而且,我在打开它给的几个其他演示事例的时候的速度不是一般地慢,有几个甚至打不开,据有的网友说打开时竟然加载了12M的页面,狂汗。