Service Stack 与 WCF

本文转载自 http://www.cnblogs.com/shanyou/p/3348347.html

 

ServiceStack是一个开源的、支持.NET与Mono平台的REST Web Services框架。同类产品微软自有的是WCF。

Web服务通常有远程过程调用(RPC)和RESTful (HTTP)两类,现在占据主导地位的Web服务是RESTful (HTTP)

 

    ServiceStack的组件见下:

包含高性能Razor Engine的Web应用框架;

支持例如HTML,XML,JSON,SOAP等多种格式的基于消息的Web服务框架;

包含内建IOC(Inversion of Control)的容器;若干内建库文件,诸如:Text serializer,Redis Client,ORM以及caching providers;

除了ASP.NET Hosting和Mono Hosting之外,还包含self-hosting选项。

 

    2年前REST就已经成为Web API部署方式的主流了,而且一直保持这种发展势头,现在基本上都是REST服务,SOAP在企业内网还存在.

    远程过程调用 (RPC) ,每个请求旨在类似于函数调用:

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

    RPC 方法对服务的修改非常不友好。 例如前面的代码段,如果要求从客户端来执行更高版本的 Web 服务的 DoSomething 方法的两个输入参数 — 或需要返回字符串值之外的另一个字段 —— 给老客户重大更改是不可避免的。 当然,您始终可以创建平行的 DoSomething_v2 方法,要带两个输入的参数,但久而久之会搞乱您的 Web 服务接口和消费者,服务变得越来越丑,用WCF实现的Web服务就是属于这种情况。

 

    本文假定您有一些熟悉 WCF 和.NET 框架。 为了更好地展示WCF 概念可以如何转化为 ServiceStack 的概念,首先会在WCF中实现服务层。我会告诉你如何通过将WCF Web 服务移植到等效的使用 ServiceStack 转换为跨平台的 Web 服务。

//WCF的契约:
[DataContract] 
    public class Ticket 
    { 
        [DataMember] 
        public int TicketId { get; set; } 
        [DataMember] 
        public int TableNumber { get; set; } 
        [DataMember] 
        public int ServerId { get; set; } 
        [DataMember] 
        public List Orders { get; set; } 
        [DataMember] 
        public DateTime Timestamp { get; set; } 
    } 
    [ServiceContract] 
    public interface ITicketService 
    { 
        ///  
        /// 检索当前队列中的所有门票的完整清单 
        ///  
        ///  
        [OperationContract] 
        List GetAllTicketsInQueue();

        ///  
        /// 新增新门票 
        ///  
        ///  
        [OperationContract] 
        void QueueTicket(Ticket ticket);

        ///  
        /// 从队列拉出一张票 
        ///  
        ///  
        [OperationContract] 
        Ticket PullTicket(); 
    } 
}


//把它转换为ServiceStack的契约:
public class Ticket 
{ 
       public int TicketId { get; set; } 
        public int TableNumber { get; set; } 
        public int ServerId { get; set; } 
        public List Orders { get; set; } 
        public DateTime Timestamp { get; set; }

}

public class GetAllTicketsInQueueRequest 
{ 
}

public class QueueTicketRequest 
{ 
    public Ticket Ticket { get; set; } 
}

public class PullTicketRequest 
{ 
}

public interface ISCTicketService 
{ 
    List Any(GetAllTicketsInQueueRequest request);

    void Any(QueueTicketRequest request);

    Ticket Any(PullTicketRequest request); 
}

ServiceStack 规定每个唯一的请求是对象所标识唯一的请求,这意味着你不能重用 DTO 跨多个服务实现与 ServiceStack 的请求。ServiceStack 支持不同的操作,如有 Get 和 Post。 您的选择在这里仅影响的 HTTP 请求。 指定任何 Web 服务请求是指可以通过 HTTP GET 和 HTTP POST 调用操作。 这种强制措施,简化了 rest 风格的 Web 服务实现。要将您的 ServiceStack Web 服务变成 rest 风格的 Web 服务,只需添加 URL [Route(...)]向您的 Web 服务请求声明属性。

    //Request DTO 
    public class Hello 
    { 
        public string Name { get; set; } 
    }

    //Response DTO 
    public class HelloResponse 
    { 
        public string Result { get; set; } 
        public ResponseStatus ResponseStatus { get; set; } //Where Exceptions get auto-serialized 
    }

    //Can be called via any endpoint or format, see: http://servicestack.net/ServiceStack.Hello/ 
    public class HelloService : Service 
    { 
        public object Any(Hello request) 
        { 
            return new HelloResponse { Result = "Hello, " + request.Name }; 
        } 
    }

    //REST Resource DTO 
    [Route("/todos")] 
    [Route("/todos/{Ids}")] 
    public class Todos : IReturn> 
    { 
        public long[] Ids { get; set; } 
        public Todos(params long[] ids) 
        { 
            this.Ids = ids; 
        } 
    }

    [Route("/todos", "POST")] 
    [Route("/todos/{Id}", "PUT")] 
    public class Todo : IReturn 
    { 
        public long Id { get; set; } 
        public string Content { get; set; } 
        public int Order { get; set; } 
        public bool Done { get; set; } 
    }

    public class TodosService : Service 
    { 
        public TodoRepository Repository { get; set; }  //Injected by IOC

        public object Get(Todos request) 
        { 
            return request.Ids.IsEmpty() 
                ? Repository.GetAll() 
                : Repository.GetByIds(request.Ids); 
        }

        public object Post(Todo todo) 
        { 
            return Repository.Store(todo); 
        }

        public object Put(Todo todo) 
        { 
            return Repository.Store(todo); 
        }

        public void Delete(Todos request) 
        { 
            Repository.DeleteByIds(request.Ids); 
        } 
    }   

以ASP.NET Hosting承载ServiceStack,创建一个空的ASP.NET应用,使用 NuGet 包管理器控制台将 ServiceStack 引用添加到 ServiceStack.Host.AspNet中所示

 

Web.config 会增加下面的配置



你需要从 ServiceStack.WebHost.End 继承­实现端点。

public class AppHost  : AppHostBase 
    {        
        public AppHost() //Tell ServiceStack the name and where to find your web services 
            : base("StarterTemplate ASP.NET Host", typeof(HelloService).Assembly) { }

        public override void Configure(Funq.Container container) 
        { 
            //Set JSON web services to return idiomatic JSON camelCase properties 
            ServiceStack.Text.JsConfig.EmitCamelCaseNames = true; 
        
            //Configure User Defined REST Paths 
            Routes 
              .Add("/hello") 
              .Add("/hello/{Name*}");

            //Uncomment to change the default ServiceStack configuration 
            //SetConfig(new EndpointHostConfig { 
            //});

            //Enable Authentication 
            //ConfigureAuth(container);

            //Register all your dependencies 
            container.Register(new TodoRepository());            
        }

        /* Uncomment to enable ServiceStack Authentication and CustomUserSession 
        private void ConfigureAuth(Funq.Container container) 
        { 
            var appSettings = new AppSettings();

            //Default route: /auth/{provider} 
            Plugins.Add(new AuthFeature(() => new CustomUserSession(), 
                new IAuthProvider[] { 
                    new CredentialsAuthProvider(appSettings), 
                    new FacebookAuthProvider(appSettings), 
                    new TwitterAuthProvider(appSettings), 
                    new BasicAuthProvider(appSettings), 
                }));

            //Default route: /register 
            Plugins.Add(new RegistrationFeature());

            //Requires ConnectionString configured in Web.Config 
            var connectionString = ConfigurationManager.ConnectionStrings["AppDb"].ConnectionString; 
            container.Register(c => 
                new OrmLiteConnectionFactory(connectionString, SqlServerDialect.Provider));

            container.Register(c => 
                new OrmLiteAuthRepository(c.Resolve()));

            var authRepo = (OrmLiteAuthRepository)container.Resolve(); 
            authRepo.CreateMissingTables(); 
        } 
        */

        public static void Start() 
        { 
            new AppHost().Init(); 
        } 
    }

 

ServiceStack Web 应用程序启动时,您的服务合同列出作为元数据操作,如图所示:

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页