国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

使用ServiceStack構建Web服務

2019-11-17 02:54:37
字體:
來源:轉載
供稿:網友

使用ServiceStack構建Web服務

提到構建WebService服務,大家肯定第一個想到的是使用WCF,因為簡單快捷嘛。首先要說明的是,本人對WCF不太了解,但是想快速建立一個WebService,于是看到了MSDN上的這一篇文章 Building Cross-Platform Web Services with ServiceStack,所以這里簡要介紹一下如何使用ServiceStack快速建立一個WebService服務。

當然,在開始之前,首先要說明一下ServiceStack是個什么東西。 在國內用ServiceStack的似乎很少,大部分都是WCF或者asp.net WebAPI,唯一接觸ServiceStack的可能是在C# 中調用Redis的時候,有個ServiceStack.Redis,之前還寫過一篇 .NET中使用Redis 的拙文。這個ServiceStack.Redis其實就是ServiceStack的一個組件,專門用來跟Redis進行交互的。

一 關于WebService

在談論ServiceStack之前,先看看構成一個WebService的基本框架:

Print

服務層就是定義WebService接口的地方,這一層也是客戶端使用WebService唯一需要與之交互的一層。

業務層通常包含有大量的業務邏輯。他也是實現接口層定義的接口的地方,也是保持服務層的輕量以及關注服務端客戶端的契約以及通訊的地方。

數據層通常就是封裝數據訪問方法并給業務層提供抽象數據模型。

現在我們來看Service這一層。一些WebService使用遠程過程調用的方法來實現(RPC),比如會定義如下函數調用:

public interface IService{    string DoSomething(int input);}

這種RPC的方式使得服務不能很好的應對變化。比如,在上面的代碼中,如果后續版本的接口需要接受兩個參數來執行DoSomething方法,或者說除了返回一個string外還需要返回其他信息。如果在原接口上修改的話,就會使得老版本的客戶端無法使用。當然,我們可以創建一個平行的DoSomething_v2來接受兩個參數。但是隨著時間的遷移,我們的接口中會充斥著越來越多這樣的定義,不管是新用戶還是老用戶都會感到困惑。

面對這種情況,可以使用數據傳輸對象(DTO) 來定義前面的接口中的相關參數。上面的RPC方式轉換為對應的DTO模型如下:

public class DoSomethingRequest{    public int Input { get; set; }}public class DoSomethingResponse{    public string Result { get; set; }}public interface IService{    DoSomethingResponse DoSomething(DoSomethingRequest request);}

每個服務接受一個DTO請求參數,返回一個DTO響應。在請求和相應的DTO對象中添加字段,不會破壞舊的客戶端。

在WCF中RPC和DTO風格的WebService均支持,但是在ServiceStack中僅支持DTO風格。ServiceStack為了減少繁瑣和注重接口設計從而僅擁抱的DTO風格的遠程 WebService接口。 這是了解 ServiceStack的關鍵,也是ServiceStack框架的設計原則。

了解了ServiceStack的設計理念后,來看看ServiceStack是什么。

二 ServiceStack是什么

ServiceStack是一個開源的十分流行的WebService框架,引用其官網的介紹:

“Service Stack is a high-performance .NET web services platform that simplifies the development of high-performance REST (JSON, xml, JSV, HTML, MsgPack, PRotoBuf, CSV) and WCF SOAP Web Services.”

“ServiceStack是一個高性能的.NET Web Service 平臺,他能夠簡化開發高性能的REST (支持JSON,XML,JSV,HTML,MsgPack,ProtoBuf,CSV等消息格式)以及WCF SOAP風格的WebService”。

在其主頁上也有一篇名為What is the ServiceStack的介紹。建議您直接看,這里從里面截取了幾張圖:

more than service

可以看到ServiceStack除了在其底層是一個精簡的WebService框架之外,在其上還有與之相關的一些組件,比如號稱.NET 上最快的JSON序列化工具,.NET中流行的Redis訪問模塊,輕量級快速Orm框架OrmLite等諸多功能。

what is service stack

可以看到這些組件基本提供了一個WebService框架必需的一些功能。

Visualizing ServiceStack

在內部實現上ServiceStack建立在原生的ASP.NET IHttpHandler之上,他能夠允許在.NET Framework和Mono之上。

下面來看如何使用ServiceStack建立一個WebService:

三 使用ServiceStack

要創建服務,首先要定義接口。這里以一個售票系統為例來說明如何使用ServiceStack來創建服務:

創建服務接口層

首先新建一個TicketSystem.ServiceContract的類庫,我們定義DTO對象。必需要有一個Ticket實體類:

public class Ticket{    public int TicketId { get; set; }    public int TableNumber { get; set; }    public int ServerId { get; set; }    public List<Order> Orders { get; set; }    public DateTime Timestamp { get; set; }}

在WCF中需要在實體類和字段上面添加DataContract和DataMember來表示序列化時需要的字段,如果沒有添加這些標簽,在序列化的時候就會忽略。

而在ServiceStack中,這些標記都不需要,ServiceStack會序列化所有的Plain Old CLR Objects(POCOs),并且這些對象對客戶端都可見。

然后開始定義Service中需要用到的對外提供服務的接口:

public interface ITicketService{    List<Ticket> Any(GetAllTicketsInQueueRequest request);    void Any(QueueTicketRequest request);    Ticket Any(PullTicketRequest request);}

在ITickertService中,我們定義了三個操作,第一次看到這樣的操作可能有些奇怪,因為方法名稱都一樣。這是ServiceStack和WCF不一樣的地方。在WCF中以上接口可能是這樣的:

[ServiceContract]public interface ITicketService{    [OperationContract]    List<Ticket> GetAllTicketsInQueue(GetAllTicketsInQueueRequest request);    [OperationContract]    void QueueTicket(QueueTicketRequest request);    [OperationContract]    Ticket PullTicket(PullTicketRequest request);}

WCF中接口需要使用ServiceContract來表明,其中的方法需要使用OperationContract來標記。方法的名稱就是服務的名稱。

ServiceStack中的服務方法名為Any,Get以及Post,這也是ServiceStack支持的請求類型,Any表示服務可以通過HTTP Get和HTTP Post兩種方式調用。這強化和簡化了RESTFull風格的WebService的實現。只需要在這些方法上添加愛[Route(&hellip;)]屬性即可。在ServiceStack中,方法和方法之間的區別是通過服務的參數及請求對象Request DTO來區分的,而不是像WCF中通過方法名稱來區分。這就表示一個請求DTO對象不能在ServiceStack的多個Service中復用。

創建服務端

有了服務接口層之后,需要編寫服務端以實現這些邏輯,也就是前面定義的ITicketService接口。首先創建名為ServiceStackServer的空的ASP.NET 應用程序,然后新建TicketService類,是該類實現ITicketService接口并繼承自Service類。Service類是ServiceStack中的,可以通過NuGet來安裝和引用ServiceStack相關類庫:

Managet NuGet Packages

實現后TicketService類如下:

public class TicketService : Service, ITicketService{    private static readonly TicketSystem.TicketProcessor.TicketProcessor        _ticketProcessor = new TicketSystem.TicketProcessor.TicketProcessor();    public List<Ticket> Any(GetAllTicketsInQueueRequest request)    {        return _ticketProcessor.GetTicketsInQueue()            .Select(TicketTranslator.TranslateTicket).ToList();    }    public void Any(QueueTicketRequest request)    {        _ticketProcessor.QueueTicket(            TicketTranslator.TranslateTicket(request.Ticket));    }    public Ticket Any(PullTicketRequest request)    {        TicketSystem.TicketProcessor.Ticket nextTicket =            _ticketProcessor.PullTicket();        if (nextTicket != null)        {            return TicketTranslator.TranslateTicket(nextTicket);        }        return null;    }}

這里面我們定義了一個私有了TicketProcessor 變量,接口中的所有方法都通過該類實現,在接口對象到該方法的調用中,我們對實體進行了轉換。該對象在其他程序集中定義,這樣能保證服務端代碼簡潔。

有了服務端之后,需要把服務端Host起來對外提供服務,ServiceStack提供了通過IIS,Self-Host等多種形式。因為我們之前創建的ASP.NET程序,所以,只需要再添加一個Global.asax文件,然后在啟動的事件application_Start中初始化即可。

protected void Application_Start(object sender, EventArgs e){    //Initialize your web service on startup.    new TicketServiceHost().Init();}

public class TicketServiceHost : AppHostBase{    //Register your web service with ServiceStack.    public TicketServiceHost()         : base("Ticket Service", typeof(TicketService).Assembly)     { }    public override void Configure(Funq.Container container)    {        //Register any dependencies your services use here.    }}

只需要實現ApphostBase基類,提供服務顯示名稱,以及實現了Service接口的服務所在的程序集即可。

當然也可以通過控制臺應用程序來Host我們的WebService,這時TicketServiceHost需要實現AppSelfHostBase,實現如下:

public class TicketServiceHost : AppSelfHostBase{    /// <summary>    /// Default constructor.    /// Base constructor requires a name and assembly to locate web service classes.     /// </summary>    public TicketServiceHost()        : base("WebApplication1", typeof(TicketService).Assembly)    {    }    /// <summary>    /// Application specific configuration    /// This method should initialize any IoC resources utilized by your web service classes.    /// </summary>    /// <param name="container"></param>    public override void Configure(Container container)    {        //Config examples        //this.AddPlugin(new PostmanFeature());        //this.AddPlugin(new CorsFeature());    }}

然后在Main函數中,啟動即可:

static void Main(string[] args){    var listeningOn = args.Length == 0 ? "http://*:1337/" : args[0];    var appHost = new TicketServiceHost()        .Init()        .Start(listeningOn);    Console.WriteLine("AppHost Created at {0}, lis
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阆中市| 阳原县| 东兴市| 临邑县| 获嘉县| 宜昌市| 清远市| 土默特左旗| 赤峰市| 三亚市| 盐山县| 夏邑县| 噶尔县| 肥乡县| 牙克石市| 济阳县| 阳春市| 中西区| 西和县| 馆陶县| 柳河县| 手游| 邛崃市| 北京市| 郓城县| 莫力| 怀安县| 厦门市| 甘谷县| 盖州市| 诏安县| 班戈县| 双江| 出国| 根河市| 奉化市| 新津县| 奎屯市| 全椒县| 泾阳县| 育儿|