2016-10-27 4 views
0

Ich habe einen Dienst auf mehreren verschiedenen Servern mit sehr ähnlichen Konfigurationen ausgeführt. Ich möchte in der Lage sein, Castle Windsor WCF Facility zu verwenden, um einen Client für beliebige Endpunktadressen zu generieren.Windsor WCF Client für mehrere Endpunkte

public class ServiceFactory { 
    public IService GetService(string hostName){ 
     .... 
    } 
} 

Jetzt werde ich bei der Kompilierung wissen, was all meine Dienste sein werden, so kann ich dies tun:

var container = new WindsorContainer(); 

// ... 

container.AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero); 
container.Register(Component.For<IService>().AsWcfClient(new DefaultClientModel() 
{ 
    Endpoint = WcfEndpoint.BoundTo(new NetTcpBinding()).At("net.tcp://hostname:port") 
}).Named("hostname")); 

Und dann so meinen Servicefactory tun:

public class ServiceFactory 
{ 
    private readonly IWindsorContainer _container; 

    public ServiceFactory(IWindsorContainer container) 
    { 
     _container = container; 
    } 

    public IService GetService(string hostName) 
    { 
     return _container.Resolve<IService>(hostName); 
    } 
} 

Aber das ist nicht robust gegen mich zu vergessen, einen bestimmten Endpunkt zu konfigurieren. Gibt es eine elegantere Lösung?

Antwort

0

Ich musste den WCF Facility-Quellcode durchsuchen, aber JA! Es gibt eine elegantere Lösung:

Die WCF-Funktion ist in die Typed Factory Facility integriert, die zur dynamischen Erstellung von Fabriken zur Laufzeit verwendet wird. Die WCF-Funktion fügt der Typed Factory-Einrichtung Funktionen zum Auflösen von Fabriken hinzu, die eine Dienstverbindung von einem IWcfEndpoint herstellen.

Insbesondere ist es weiß, wie eine Factory-Methode in Form zu lösen:

IService Create(IWcfEndpoint endpoint); 

Wo IService etwas mit dem [ServiceContract] Attribut ist.

Zuerst mache ich meine Service-Fabrik sind abhängig von einer Func<IWcfEndpoint,IService>:

public class ServiceFactory { 
    public ServiceFactory(Func<IWcfEndpoint, IService> resolveService){ 
     _resolveService = resolveService; 
    } 

    public IService GetService(string hostName){ 
     return _resolveService(WcfEndpoint.BoundTo(new NetTcpBinding()).At($"net.tcp://{hostName}:port")); 
    } 
} 

dann bei der Installation, füge ich die TypedFactoryFacility:

var container = new WindsorContainer(); 

// ... 

container.AddFacility<TypedFactoryFacility>(); 
container.AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero); 
container.Register(
    Component.For<Func<IWcfEndpoint, IService>>().AsFactory(), 
    Component.For<ServiceFactory>().ImplementedBy<ServiceFactory>()); 

Windsor wird dann eine Servicefactory, etwas schaffen, das eine für fragt und verdrahten Sie es, um einen IS - Service - Client von einem Hostnamen zu erstellen:

public class FooClass { 
    public FooClass(ServiceFactory serviceFactory){ 
     var service = serviceFactory.GetService("localhost"); 
    } 
}