Здравствуйте, mDmitriy, Вы писали:
Если я правильно понял то ,что вы хотите, то это выглядит так:
Нужно уметь получать в runtime список всех хостящихся в процессе WCF-сервисов, причем мы не имеем возможности контролировать объявление и инициализацию этих сервисов (навешивать атрибуты, менять конфигурацию, использовать свой ServiceHost, ...). Иными словами — код запускающий сервисы для нас "черный ящик", и мы можем только обращаться к инфраструктeре WCF
.
Честно говоря, я не знаю простого и "законного" (т.е. через какое-то публичное API инфраструктуры WCF) способа получить общую информацию обо всех экземпляров сервисов, запущенных в текущем процессе.
Т.е. из того, что я знаю — каждый экземпляр сервиса (ну и всей обвязки вокруг: ServiceHost, всякие Dispatchers, ...) — независим от остальных. Т.е. никакого внутреннего реестра запущенных сервисов нет (ну или не понятно как до него добраться).
Из того, что мало-мальски можно предложить — это "инъекции" behaviours. Например, если написать вот такой
| Endpoint behavior |
| public class EndpointSpyBehavior : IEndpointBehavior
{
public static List<Uri> Endpoints = new List<Uri>();
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
EndpointSpyBehavior.Endpoints.Add(endpoint.Address.Uri);
}
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
}
|
| |
А к нему
| BehaviorExtensionElement |
| public class EndpointSpyBehaviorExtensionElement : BehaviorExtensionElement
{
public override Type BehaviorType
{
get { return typeof(EndpointSpyBehavior); }
}
protected override object CreateBehavior()
{
return new EndpointSpyBehavior();
}
}
|
| |
То можно будет добавить вот такое в конфиг
| App.config |
| <configuration>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior>
<mySpy/>
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="mySpy"
type="WcfExtending.EndpointSpyBehaviorExtensionElement, WcfExtending"/>
</behaviorExtensions>
</extensions>
</system.serviceModel>
</configuration>
|
| |
И можно будет получить список всех endpoints:
| Типа код консольки |
| static void Main(string[] args)
{
var serviceHost = new ServiceHost(typeof(Service), new Uri("http://localhost:13056"));
var serviceHost2 = new ServiceHost(typeof(Service), new Uri("http://localhost:15401"));
serviceHost.Open();
serviceHost2.Open();
EndpointSpyBehavior.Endpoints.ForEach(u => Console.WriteLine(u));
Console.ReadLine();
serviceHost.Close();
serviceHost2.Close();
}
|
| |
НО!!!
Это работает только если нигде никакой endpoint не ссылается ни на какой behavior configuration (тогда берется дефолтовая). Т.е. если поменять конфиг на такой:
| App.config с явной ссылкой на behavior configuration |
| <configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<system.serviceModel>
<services>
<service name="WcfExtending.Service">
<endpoint behaviorConfiguration="VVV"
binding="basicHttpBinding"
address="http://localhost:1300"
contract="WcfExtending.Service"
>
</endpoint>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="VVV"/>
<behavior>
<mySpy/>
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="mySpy"
type="WcfExtending.EndpointSpyBehaviorExtensionElement, WcfExtending"/>
</behaviorExtensions>
</extensions>
</system.serviceModel>
</configuration>
|
| |
Или аналогичное сделать в коде (т.е. указать behavior configuration явно там) — всё, behavior configuration по умолчанию (он без имени) подхватываться не будет.
Теоретически можно добавить еще ServiceBehavior (примерно так же делается) и в нем смотреть — если для endpoint наш behavior не добавлен, то добавить.
Но это тоже полумеры (ломается так же — у сервиса явно указан свой behavior