c# - 在单个 Windows 服务中托管数十个 WCF 服务的正确方法是什么?

标签 c# wcf windows-services servicehost

我的任务是将数十个 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
        };
    }
}

除了不遵循此处的“不要重复自己”规则(实际代码不同)之外,这是否是我应该在 Windows 服务代码中托管这些 WCF 服务的方式?

最佳答案

Hans,你说得对,但我会替换你的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);
    }

关于c# - 在单个 Windows 服务中托管数十个 WCF 服务的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8069854/

相关文章:

c# - ASP.NET 如何将隐藏字段和具有可见性属性的文本框呈现为 false?

c# - WCF 数据服务身份验证

c# - 如何写入自定义事件日志?

c# - MySql.Data错误: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use

WCF 客户端列表<>

WCF REST 与 Windows Phone 通信

c# - 如何将 DynamicProxy "really"向下转换回其原始类型(通过 WCF 发送)

c# - Windows 服务未完全启动

c# - TopShelf 如何捕获像 'install' 或 'start' 这样被我的 Main 方法忽略的参数?

c# - (用 Jill 反序列化动态对象?