2011-11-09 26 views
2

我的任務是將幾十個WCF服務轉移到單個Windows服務。我已經使用Windows服務模板創建一個Windows服務,並添加以下代碼ServiceHostController:在單個Windows服務中託管幾十個WCF服務的正確方法是什麼?

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服務?

+3

我寧願每個主機WCF服務的一個窗口服務,而不是2合1,原因找茬,並延伸服務是通過這種方式更容易。 –

+0

爲什麼選擇Windows服務而不是IIS或WAS? –

+0

@Terry - 從Rambo引用Murdock第一部血液第二部分「我沒有下訂單,我就像你一樣......」據我所知,這是由於部署使用Win XP的機器。 – 5StringRyan

回答

3

漢斯,你有一切權利,但我會替換你的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); 
    } 
+0

我可以看到第2步,你正在實現類映射到我的服務程序集本身提供的接口,但我不知道你爲什麼從app.config文件中讀取端點。你能解釋一下嗎? – 5StringRyan

+0

我知道你會問這個問題,這是我們控制客戶特定終點的方式,例如說客戶定製的實現,我們正在與他們現有的系統進行接口連接。所以這就是我們關閉其他客戶端點的方式。它給你你想要揭露的能力。 –

+0

儘管我沒有使用提供的功能(因爲我不需要擔心客戶特定的終端),但我已經接受了您的答案。 – 5StringRyan

相關問題