Как правильно разместить десятки служб WCF в одной службе Windows? - PullRequest
2 голосов
/ 09 ноября 2011

Мне было поручено перевести десятки Служб WCF в одну Службу Windows. Я создал службу Windows с помощью шаблона службы Windows и добавил следующий код в ServiceHostController:

public partial class ServiceHostController : ServiceBase
{
    private List<ServiceHost> serviceHosts;

    public ServiceHostController()
    {
        InitializeComponent();
        this.ServiceName = "WCFServices";
        this.CanStop = true;
        this.AutoLog = true;
    }

    protected override void OnStart(string[] args)
    {
        if (serviceHosts != null)
        {
            foreach (var service in serviceHosts)
            {
                service.Close();
            }
        }

        InitializeServices();
        foreach (var service in serviceHosts)
        {
            service.Open();
        }
    }

    protected override void OnStop()
    {
        if (serviceHosts != null)
        {
            foreach (var service in serviceHosts)
            {
                service.Close();
            }
            serviceHosts.Close(); = null;
        }

        foreach (var service in serviceHosts)
        {
            service.Close();
        }
    }

    private void InitializeServices()
    {
        serviceHosts = new List<ServiceHost>()
        {
            new ServiceHost(typeof(WCFService1)),
            new ServiceHost(typeof(WCFService2)),
            // add dozens of services here
        };
    }
}

Помимо несоблюдения здесь правила «Не повторять себя» (реальный код отличается), вот как я должен размещать эти службы WCF в коде службы Windows?

1 Ответ

3 голосов
/ 10 ноября 2011

Ганс, вы все правильно поняли, но я заменю ваши InitializeServices (); со следующим кодом. Это псевдокод, поэтому вам нужно заменить биты:)

1) Настройте свои конечные точки в app.config

2) Получите типы ваших сервисов из вашего сервисного проекта \ сборки

  Dictionary<Type, Type> mappings = new Dictionary<Type,Type>();

   foreach (Type t in MyServiceAssembly.GetTypes())
  {
    if (t.GetInterfaces().Length > 0)
    {
      foreach (Type ti in t.GetInterfaces())

        {
          if (mapping.ContainsKey(ti))
            System.Diagnostics.Debug.WriteLine("Class {0} implements more than one interface {1}", t.FullName, ti.FullName);
          else
            mapping.Add(ti, t);

          // System.Diagnostics.Debug.WriteLine("Class {0} implements {1}", t.FullName, ti.FullName);
        }
    }
  }

4) Если вы хотите контролировать конечные точки из app.config Теперь итерируйте свои конечные точки и получите соответствующую реализацию сервиса, затем создайте ваши хосты

// читать ваши конечные точки при запуске службы

 List<ServiceHost> serviceHosts = new List<ServiceHost>();

     ServicesSection servicesSection = (ServicesSection)WebConfigurationManager.GetSection("system.serviceModel/services");  

    for(int i = 0;i<servicesSection.Services.Count;i++)
    {
    ServiceEndpointElement endpoint = servicesSection.Services[i].Endpoints[0];  
    string url = string.Format("net.tcp://{0}:{1}/YouNameSpace_service_Name_From_EndPoint/{2}.svc","YourHost","YourPort");
      ServiceHost serviceHost = new ServiceHost(mappings[endpoint.Contract] , new Uri(url));

              serviceHost.Open();

              mServiceHosts.Add(serviceHost);
    }

5) Если вы не хотите управлять конечными точками из app.config , выполните итерацию по списку сопоставлений.

// сделать это при запуске службы

 List<ServiceHost> serviceHosts = new List<ServiceHost>();

     foreach(type t in mappings.Keys)
    {
            string url = string.Format("net.tcp://{0}:{1}/YouNameSpace_{2}.svc","YourHost","YourPort",t.name);
      ServiceHost serviceHost = new ServiceHost(mappings[t] , new Uri(url));

              serviceHost.Open();

              mServiceHosts.Add(serviceHost);
    }
...