Spring.NET教程(二十一)整合Web Service(應用篇)
雖然目前.net對WebService支持的非常好,Spring.NET認為還是有幾個方面可以改進:
第一、.NET在.asmx文件中保存WebService請求和服務對象的關聯關系,這些.asmx文件不管有用沒用都得放在那兒。
第二、Spring.NET希望能通過IoC容器對WebService進行依賴註入。一般說來WebService總會依賴其它服務對象,所以,如果能用配置方式來選擇服務對象,這個功能就相當強大了。
第三、目前在.NET中WebService的創建完全是一個實現(特定類型)的過程。多數服務(雖不能說是全部)都應實現為使用粗粒度服務接口的普通類型,並且,某個對象能否發布為遠程對象、WebService還是企業(COM+)組件應該只與配置有關,而不應該取決於它的實現方式。
ASP.NET用.aspx文件來保存表示層代碼,用code-behind文件中的類保存應用邏輯,.aspx與類代碼文件各有分工;但WebService卻不同,WebService的邏輯完全是在code-behind的類中實現的。.asmx文件並沒有什麽真正的用途,實際上,這個文件既沒有必要存在、也不應該存在。
在將WebServiceFactoryHandler類註冊為響應*.asmx請求的HTTP Handler之後,開發人員就可以在IoC容器中用標準的Spring.NET對象定義來發布WebService。在以外編寫WebService的過程中,需要增加兩個特性:方法級的[WebMethod]及類型級的[WebService]。要想將這個對象發布為WebService,只需依次作以下操作:在web.config文件中,將Spring.Web.Services.WebServiceFactoryHandler註冊為響應*.asmx請求的HTTP Handler。
在客戶端,.NET本身最大的缺陷是將客戶端代碼綁定在了代理類而非服務接口上。除非按照Jubal Lowy的著作《Programming .NET Components》中提到的方法,手工讓代理類實現某個服務接口,否則應用程序代碼的靈活性會很低,同時,如果需要使用一個新的、改進過的WebService類,或者打算用一個本地服務替換掉WebService時,相應的更換工作會很復雜。 在Spring.NET的支持下,可以很方便的為WebService創建實現了指定服務接口的客戶端代理。
準備條件:
[Serializable]
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public interface IPersonContract
{
void SavePerson(Person model);
Person GetPerson();
}
PersonContract
public class PersonContract : IPersonContract
{
private Person m_person;
public void SavePerson(Person model)
{
this.m_person = model;
this.m_person.Name += "冬";
this.m_person.Age++;
}
public Person GetPerson()
{
return this.m_person;
}
}
服務器端:
首先讓我在Web.config中增加配置
</httpModules>
<add name="Spring" type="Spring.Context.Support.WebSupportModule, Spring.Web"/>
</httpModules>
WebServiceHandlerFactory
</system.webServer>
</handlers>
<add name="SpringWebServiceSupport" verb="*" path="*.asmx" type="Spring.Web.Services.WebServiceHandlerFactory, Spring.Web"/>
</handlers>
</system.webServer>
objects
<objects XMLns="http://www.springFramework.net">
<object id="PersonContract" type="SpringNetWebService.PersonContract,SpringNetWebService"/>
<object id="PersonContractServer" type="Spring.Web.Services.WebServiceExporter, Spring.Web">
<property name="TargetName" value="PersonContract"/>
<property name="Namespace" value="http://tempuri.org/"/>
<property name="Description" value="劉冬編寫的Spring.NET整合WebService的例子"/>
<property name="MemberAttributes">
<dictionary>
<entry key="GetPerson">
<object type="System.Web.Services.WebMethodAttribute, System.Web.Services">
<property name="Description" value="獲取Person的方法描述"/>
<property name="MessageName" value="獲取Person"/>
</object>
</entry>
<entry key="SavePerson">
<object type="System.Web.Services.WebMethodAttribute, System.Web.Services">
<property name="Description" value="保存Person的方法描述"/>
<property name="MessageName" value="保存Person"/>
</object>
</entry>
</dictionary>
</property>
</object>
</objects>
在Global.asax的Application_Start中實例化Spring.net容器
WebApplicationContext ctx = ContextReGIStry.GetContext() as WebApplicationContext;
運行效果:
客戶端:
App.config
<object id="PersonServer" type="Spring.Web.Services.WebServiceProxyFactory, Spring.Services">
<!--服務器Uri-->
<property name="ServiceUri" value="http://localhost:1600/PersonContractServer.asmx"/>
<!--服務契約-->
<property name="ServiceInterface" value="IContract.IPersonContract, IContract"/>
<property name="ProductTemplate">
<object>
<!--超時時間10000毫秒-->
<property name="Timeout" value="10000" />
</object>
</property>
</object>
Program
class Program
{
static void Main(string[] args)
{
IApplicationContext ctx = ContextRegistry.GetContext();
IPersonContract server = ctx.GetObject("PersonServer") as IPersonContract;
Person tempPerson = server.GetPerson();
tempPerson = tempPerson ?? new Person() { Name = "劉冬", Age = 26 };
server.SavePerson(tempPerson);
Person person = server.GetPerson();
string msg = person == null ? "對象為空" : string.Format("姓名:{0},年齡:{1}", person.Name, person.Age);
Console.WriteLine(msg);
Console.ReadLine();
}
}
Spring.NET教程(二十一)整合Web Service(應用篇)