2012-04-10 27 views
6

Üç derlemeler oluşturdum. Bir web sitesi, bir WCF servisi ve hizmetlerin uyguladığı arayüzleri barındıran bir sözleşme düzeneği. Castle Windsor'u kullanmak istediğim her hizmet için web sitesinin web.config'inde bir son noktaya sahip olmamak için istemci (web sitesi) üzerinde hizmetlerim oluşturmak için kullanmak istiyorum.İstemci uç noktaları oluşturmak için Castle WCfFacility özelliğini kullanma

Sözleşme düzenine bakmak ve tüm hizmet arabirimlerini bir ad alanında almak istiyorum. Şu anda her servis için bileşenleri kabine kaydederken aşağıdaki gibi bir şeyim var.

ve web.config dosyasında kurulum kodum var.

<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> 

Bütün neredeyse tamamen aynı görünüyor ve biz müşteriler makineleri üzerine dağıtmak ne zaman taban URL her biri için aynı olsa bile her bitiş noktasının adresini belirlemek zorunda çoklu servis uç noktaları ile bitirmek.

Web.config sayfamda kod aracılığıyla yakalanan ve daha sonra kontratlar meclisinde yansıma kullanarak konteynere kayıtlı servislerin bulunduğu bir temel url'ye sahip olmak isterim. Yukarıdaki yapılandırma dosyasında bulunan özel son nokta davranışına ihtiyacım var.

Nerede başlarım? WcfFacility harika görünüyor ama doco biraz eksik ...

cevap

12

WCF tesisi için eksik olan dokümanlar konusunda hemfikirler ve bu çok üzücü çünkü gerçekten harika bir araç ve eğer insanlar '

  1. A sınıfı: t

    en sahip üç proje uygulaması oluşturalım ... başlayabilecekleri olamazdı çünkü kullanmak, bu yüzden eğer ben biraz size yardımcı olabilir bakayım Paylaşılan sözleşmeler için kütüphane
  2. Sunucu olarak işlem gören bir konsol uygulaması
  3. bir müşteri

fikri gibi davranan bir konsol uygulaması biz hizmetlerini kayıt sırasında hizmet adları kullanmaya ve temel URL paylaşmak isterler ki (ben ne soran vardı düşünüyorum ve eğer değilse, umarım sizden daha iyi tahmin edebilirsiniz.

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

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

Şimdi sunucu konsolu uygulaması şöyle

, biz öncelikle sadece orada hizmet sözleşmeler özel (yine hiçbir şey uygulamak: Yani, öncelikle paylaşılan sözleşmeler sadece (özel bir şey, normal bir WCF ücret) içinde bu vardır arayüzleri uygulayan dersler) ve sonra hepsini sadece servis olarak kaydediniz (burada herhangi bir yapılandırma dosyasına gerek yoktur ve Windsor'un size sunduğu tüm seçenekleri kullanarak hizmetler vb. karar verme şeklinizi değiştirebilirsiniz) - şemam biraz sınırlıdır ama size bir fikir verir):

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) 
     { 
     } 
    } 
} 

Sunucu, şimdi bu hizmetleri nasıl tüketirsiniz? Eh, aslında, burada oldukça kolay bir istemci konsol uygulaması (sadece sözleşmeler sınıf kitaplığına başvurur): bu kadar

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(); 
    } 
} 

- umarım bu başlamanıza olacak (bunu bulmak denemeler ve genellikle intellisense kullanarak Gitmem gereken yere varır).Size hem servis hem de müşteri tarafını gösterdim ama isterseniz birini veya diğerini kullanabilirsiniz.

Bağlamanın nerede yapılandırıldığını ve URL'leri oluşturmayla ilgili olarak nereye gittiğimi görebilmeniz gerekir. Bu durumda, temel URL'nizi kolayca bir yapılandırma dosyasından veya ne yapmak istediğinizden koparırsınız.

söz Son bir şey böyle bir şey olurdu istemci örnekte böylece, bitiş noktasına bir uzantısı olarak ekleyerek özel uç nokta davranışını ekleyebilir olmasıdır

:

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

bir gibi çalışır çekicilik, çok teşekkür ederim. –

+0

bu ne yapar? (f => f.CloseTimeout = TimeSpan.Zero) –

+0

Bu, tüm hizmetler için varsayılan closetimeout'u ayarlar - bu, "Kapat işleminin tamamlanması için sağlanan süreyi belirleyen bir TimeSpan değeri. Bu değer, Sıfır'a eşittir. Varsayılan değer 00:01:00. " - http://msdn.microsoft.com/en-us/library/ms731361.aspx adresinden. Ayrıca burada tüm olası zaman aşımlarından bahsedecek iyi bir konu: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/84551e45-19a2-4d0d-bcc0-516a4041943d/ – kmp

İlgili konular