2012-04-10 31 views
6

Tôi đã tạo ra ba hội đồng. Một trang web, một dịch vụ WCF và một hội đồng hợp đồng chứa các giao diện mà các dịch vụ thực hiện. Tôi muốn sử dụng Castle Windsor để tạo các dịch vụ cho tôi trên máy khách (website) để tôi không phải có điểm cuối trong web.config của trang web cho mỗi dịch vụ mà tôi muốn sử dụng.Sử dụng Castle Windsor Wcf Tính linh hoạt để tạo điểm cuối của khách hàng

Tôi muốn xem hợp đồng lắp ráp và nhận tất cả các giao diện dịch vụ trong không gian tên. Ngay bây giờ cho mỗi dịch vụ tôi có một cái gì đó như sau khi đăng ký các thành phần với container.

container.Register(Component.For<ChannelFactory<IMyService>>().DependsOn(new { endpointConfigurationName = "MyServiceEndpoint" }).LifeStyle.Singleton); 
container.Register(Component.For<IMyService>().UsingFactoryMethod((kernel, creationContext) => kernel.Resolve<ChannelFactory<IMyService>>().CreateChannel()).LifeStyle.PerWebRequest); 

và trong web.config của tôi Tôi có mã thiết lập.

<system.serviceModel> 
     <extensions> 
     <behaviorExtensions> 
      <add name="AuthToken" type="MyNamespace.Infrastructure.AuthTokenBehavior, MyNamespace.Contracts" /> 
     </behaviorExtensions> 
     </extensions> 
     <behaviors> 
     <endpointBehaviors> 
      <behavior> 
       <AuthToken /> 
      </behavior> 
     </endpointBehaviors> 
     </behaviors> 

     <bindings> 
     <wsHttpBinding> 
      <binding maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"> 
       <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"></readerQuotas> 
       <security mode="None" /> 
      </binding> 
     </wsHttpBinding> 
     </bindings> 

     <client> 
     <endpoint name="MyServiceEndpoint" address="http://someurl/MyService.svc" binding="wsHttpBinding" contract="MyNamespace.Contracts.IMyService"></endpoint> 
     </client> 
    </system.serviceModel> 

tôi kết thúc với nhiều điểm cuối dịch vụ mà tất cả nhìn gần như giống hệt nhau và khi chúng tôi triển khai vào máy khách máy họ phải thiết lập địa chỉ của tất cả các thiết bị đầu cuối cho dù url cơ bản là giống nhau cho mỗi người.

Tôi muốn có một url cơ sở trong web.config của mình được lấy qua mã và sau đó có các dịch vụ đã đăng ký với vùng chứa sử dụng sự phản ánh trên bản hợp đồng. Tôi cần các hành vi điểm cuối chuyên ngành đó là trong tập tin cấu hình trên.

Tôi bắt đầu từ đâu? các WcfFacility trông tuyệt vời nhưng doco là một chút thiếu ...

Trả lời

12

Tôi đồng ý các tài liệu cho các cơ sở wcf đang thiếu và đó là buồn vì nó là một công cụ thực sự tuyệt vời và nó sẽ là một sự xấu hổ thực sự nếu mọi người didn ' t sử dụng nó bởi vì họ không thể bắt đầu, vì vậy hãy để tôi xem liệu tôi có thể giúp bạn ra ngoài một chút nếu tôi có thể ...

Hãy tạo một ứng dụng ba dự án có:

  1. một lớp học thư viện cho các hợp đồng được chia sẻ
  2. Ứng dụng bảng điều khiển hoạt động với tư cách máy chủ
  3. Ứng dụng bảng điều khiển hoạt động với tư cách khách hàng

Ý tưởng là chúng tôi muốn sử dụng tên dịch vụ khi đăng ký dịch vụ và chia sẻ URL cơ sở (tôi nghĩ đó là những gì bạn đang hỏi và nếu không, hy vọng bạn có thể ngoại suy từ đây). Vì vậy, trước hết, các hợp đồng chia sẻ đơn giản là có này trong nó (không có gì đặc biệt, bình thường WCF giá vé):

[ServiceContract] 
public interface IMyService1 
{ 
    [OperationContract] 
    void DoSomething(); 
} 

[ServiceContract] 
public interface IMyService2 
{ 
    [OperationContract] 
    void DoSomethingToo(); 
} 

Bây giờ ứng dụng máy chủ giao diện điều khiển trông như thế này, trước hết chúng ta thực hiện các hợp đồng dịch vụ (một lần nữa không có gì đặc biệt đó, chỉ cần các lớp thực hiện các giao diện) và sau đó chỉ cần đăng ký tất cả các dịch vụ (thông báo không cần bất kỳ tập tin cấu hình nào ở đây và bạn có thể thay đổi cách bạn quyết định dịch vụ là gì, sử dụng tất cả các tùy chọn mà Windsor cung cấp cho bạn) cung cấp cho bạn ý tưởng):

namespace Services 
{ 
    public class MyService1 : IMyService1 
    { 
     public void DoSomething() 
     { 
     } 
    } 

    public class MyService2 : IMyService2 
    { 
     public void DoSomethingToo() 
     { 
     } 
    } 
} 

//... In some other namespace... 

class Program 
{ 
    // Console application main 
    static void Main() 
    { 
     // Construct the container, add the facility and then register all 
     // the types in the same namespace as the MyService1 implementation 
     // as WCF services using the name as the URL (so for example 
     // MyService1 would be http://localhost/MyServices/MyService1) and 
     // with the default interface as teh service contract 
     var container = new WindsorContainer();    
     container.AddFacility<WcfFacility>(
      f => f.CloseTimeout = TimeSpan.Zero); 
     container 
      .Register(
       AllTypes 
        .FromThisAssembly() 
        .InSameNamespaceAs<MyService1>() 
        .WithServiceDefaultInterfaces() 
        .Configure(c => 
           c.Named(c.Implementation.Name) 
            .AsWcfService(
             new DefaultServiceModel() 
              .AddEndpoints(WcfEndpoint 
                  .BoundTo(new WSHttpBinding()) 
                  .At(string.Format(
                   "http://localhost/MyServices/{0}", 
                   c.Implementation.Name) 
                  ))))); 

     // Now just wait for a Q before shutting down 
     while (Console.ReadKey().Key != ConsoleKey.Q) 
     { 
     } 
    } 
} 

Và đó là máy chủ, bây giờ cách sử dụng các dịch vụ này? Vâng, thực sự đó là khá dễ dàng, đây là một ứng dụng client giao diện điều khiển (nó tham chiếu chỉ là thư viện lớp hợp đồng):

class Program 
{ 
    static void Main() 
    { 
     // Create the container, add the facilty and then use all the 
     // interfaces in the same namespace as IMyService1 in the assembly 
     // that contains the aforementioned namesapce as WCF client proxies 
     IWindsorContainer container = new WindsorContainer(); 

     container.AddFacility<WcfFacility>(
      f => f.CloseTimeout = TimeSpan.Zero); 

     container 
      .Register(
       Types 
        .FromAssemblyContaining<IMyService1>() 
        .InSameNamespaceAs<IMyService1>() 
        .Configure(
         c => c.Named(c.Implementation.Name) 
           .AsWcfClient(new DefaultClientModel 
                { 
                 Endpoint = WcfEndpoint 
                  .BoundTo(new WSHttpBinding()) 
                  .At(string.Format(
                   "http://localhost/MyServices/{0}", 
                   c.Name.Substring(1))) 
                }))); 

     // Now we just resolve them from the container and call an operation 
     // to test it - of course, now they are in the container you can get 
     // hold of them just like any other Castle registered component 
     var service1 = container.Resolve<IMyService1>(); 
     service1.DoSomething(); 

     var service2 = container.Resolve<IMyService2>(); 
     service2.DoSomethingToo(); 
    } 
} 

Vậy đó - hy vọng điều này sẽ giúp bạn bắt đầu (tôi thấy rằng thử nghiệm và sử dụng IntelliSense thường đưa tôi đến nơi tôi cần đi).Tôi đã cho bạn thấy cả hai dịch vụ và phía khách hàng nhưng bạn chỉ có thể sử dụng một hoặc khác nếu bạn thích.

Bạn có thể xem vị trí của liên kết được định cấu hình và cách tôi xây dựng URL để bạn có thể dễ dàng lấy URL cơ sở từ tệp cấu hình hoặc bất kỳ điều gì bạn muốn.

Một điều cuối cùng đề cập đến là bạn có thể thêm hành vi đầu cuối tùy chỉnh của bạn bằng cách thêm nó như là một mở rộng của thiết bị đầu cuối, vì vậy trong ví dụ khách hàng mà bạn sẽ có một cái gì đó như thế này:

Endpoint = WcfEndpoint 
    .BoundTo(new WSHttpBinding()) 
    .At(string.Format("http://localhost/MyServices/{0}", c.Name.Substring(1))) 
    .AddExtensions(new AuthTokenBehavior()) 
+0

hoạt động như một quyến rũ, cảm ơn bạn rất nhiều. –

+0

việc này sẽ làm gì? (f => f.CloseTimeout = TimeSpan.Zero) –

+0

Điều đó đặt thời gian đóng mặc định cho tất cả các dịch vụ - đây là "Giá trị TimeSpan chỉ định khoảng thời gian được cung cấp cho một thao tác đóng để hoàn thành. Giá trị này phải lớn hơn hoặc bằng Zero. Mặc định là 00:01:00. " - từ http://msdn.microsoft.com/en-us/library/ms731361.aspx. Ngoài ra, đây là một chủ đề hay nói về tất cả thời gian chờ có thể có: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/84551e45-19a2-4d0d-bcc0-516a4041943d/ – kmp

Các vấn đề liên quan