2016-10-27 2 views
0

У меня есть служба, работающая на нескольких разных серверах с очень похожими конфигурациями. Я хочу иметь возможность использовать Castle Windsor WCF Facility для создания клиента для произвольных адресов конечных точек.Windsor WCF Client для нескольких конечных точек

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

Теперь я буду знать, во время компиляции, что будет все мои услуги, так что я могу это сделать:

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")); 

А потом сделать мой ServiceFactory так:

public class ServiceFactory 
{ 
    private readonly IWindsorContainer _container; 

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

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

Но я не уверен в том, что я забываю настроить конкретную конечную точку. Есть ли более элегантное решение?

ответ

0

Мне пришлось проработать исходный код объекта WCF, но ДА! существует более элегантное решение:

Объект WCF интегрирован с типовой фабричной установкой, которая используется для динамического создания заводов во время выполнения. Объект WCF добавляет функциональность в Typed Factory Facility для разрешения фабрик, которые производят сервисное соединение с IWcfEndpoint.

В частности, он знает, как решить фабричный метод в форме:

IService Create(IWcfEndpoint endpoint); 

Где IService что-то с атрибутом [ServiceContract].

Сначала я делаю мою фабрику обслуживания зависит от 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")); 
    } 
} 

Тогда при установке, я добавляю 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 затем обеспечит ServiceFactory ко всему, что просит один , и подключите его для создания клиента IService с имени хоста:

public class FooClass { 
    public FooClass(ServiceFactory serviceFactory){ 
     var service = serviceFactory.GetService("localhost"); 
    } 
} 
Смежные вопросы