Re: Найти адреса запущенных WCF-сервисов в приложении
От: Михаил Романов Удмуртия https://mihailromanov.wordpress.com/
Дата: 26.09.22 11:10
Оценка: 6 (1)
Здравствуйте, 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
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.