2014-02-11 34 views
0

中注册具有多个ServiceHost实例的MEX端点我编写了一个用于为每个服务创建并打开我的ServiceHost实例的类。我想让他们加入MEX端点。以下是创建所有主机的Register方法的代码。当我稍后循环访问主机列表并在所有主机上调用Open时,第二台主机将被打开出错,其中包含“其他信息:具有合同”IMetadataExchange“的ChannelDispatcher'_THE_MEX_ADDRESS'无法打开它IChannelListener“。如果我删除MEX代码,它运行良好并打开每个主机。我该如何解决?无法在代码

编辑:加满级

EDIT2:请记住,这是完全的代码,而不是在app.config中

public class ServiceHostMgr 
{ 
    #region Constructor 

    public ServiceHostMgr(string ip, int httpport, int nettcpport, bool discoverable) 
    { 
     _hosts = new List<ServiceHost>(); 
     _ip = ip; 
     _httpport = httpport; 
     _nettcpport = nettcpport; 
     _discoverable = discoverable; 
    } 

    #endregion 

    #region Fields 

    private string _ip; 
    private int _httpport; 
    private int _nettcpport; 
    private bool _discoverable; 
    private bool _disc = false; 

    #endregion 

    #region Properties 

    private List<ServiceHost> _hosts; 
    public List<ServiceHost> Hosts 
    { 
     get { return _hosts; } 
    } 

    #endregion 

    #region Methods 

    public ServiceHostMgr Register(Type serviceType, Type implementedContract, string path) 
    { 
     string nettcpuri = "net.tcp://" + _ip + ":" + _nettcpport.ToString(); 
     string httpuri = "http://" + _ip + ":" + _httpport.ToString(); 

     List<Uri> baseAddresses = new List<Uri>(); 
     baseAddresses.Add(new Uri(nettcpuri)); 
     if (_discoverable) 
      baseAddresses.Add(new Uri(httpuri)); 

     ServiceHost host = new ServiceHost(implementedContract, baseAddresses.ToArray()); 
     /* 
     if (_discoverable) 
     { 
      ServiceMetadataBehavior smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>(); 
      // If not, add one 
      if (smb == null) 
       smb = new ServiceMetadataBehavior(); 
      smb.HttpGetEnabled = true; 
      smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15; 
      host.Description.Behaviors.Add(smb); 
      host.AddServiceEndpoint(
       ServiceMetadataBehavior.MexContractName, 
       MetadataExchangeBindings.CreateMexHttpBinding(), 
       "mex" 
      ); 
     } 
     */ 
     if (_discoverable) 
     { 
      ServiceMetadataBehavior smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>(); 

      // If not, create new one, set values, add to collection 
      if (smb == null) 
      { 
       smb = new ServiceMetadataBehavior(); 
       smb.HttpGetEnabled = true; 
       smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15; 

       // add to behaviors collection 
       host.Description.Behaviors.Add(smb); 

       // add service endpoint 
       host.AddServiceEndpoint(
         ServiceMetadataBehavior.MexContractName, 
         MetadataExchangeBindings.CreateMexHttpBinding(), 
         "mex" 
       ); 
      } 
     } 

     NetTcpBinding nettcpbinding = new NetTcpBinding(); 
     host.AddServiceEndpoint(serviceType, nettcpbinding, nettcpuri + "/" + path); 

     _hosts.Add(host); 

     return this; 
    } 

    public ServiceHostMgr Open() 
    { 
     foreach (ServiceHost h in _hosts) 
      h.Open(); 

     return this; 
    } 

    public ServiceHostMgr Close() 
    { 
     foreach (ServiceHost h in _hosts) 
      h.Close(); 

     return this; 
    } 

    #endregion 
} 

下面是调用代码:

 ServiceHostMgr hostMgr = new ServiceHostMgr("localhost", 8012, 8002, true) 
      .Register(typeof(IPurchaseOrderSvc), typeof(PurchaseOrderSvc), "PurchaseOrder") 
      .Register(typeof(ILoginSvc), typeof(LoginSvc), "Login") 
      .Open();    

     Console.WriteLine("Running..."); 
     Console.ReadLine(); 
     hostMgr.Close(); 

回答

0

好,你正在检查,看看行为是否已经存在 - 这很好。

但即使它已经存在 - 你试图再次添加它 - 这是你的问题。

ServiceMetadataBehavior smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>(); 

// assume you found the ServiceMetadataBehavior... - you set new values 
smb.HttpGetEnabled = true; 
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15; 

// and now you're ADDING the already existing "smb" to the behaviors collection! 
host.Description.Behaviors.Add(smb); 

所以我相信你真正想要的是更多这样的:

ServiceMetadataBehavior smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>(); 

// If not, create new one, set values, add to collection 
if (smb == null) 
{ 
    smb = new ServiceMetadataBehavior(); 
    smb.HttpGetEnabled = true; 
    smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15; 

    // add to behaviors collection 
    host.Description.Behaviors.Add(smb); 

    // add service endpoint 
    host.AddServiceEndpoint(
      ServiceMetadataBehavior.MexContractName, 
      MetadataExchangeBindings.CreateMexHttpBinding(), 
      "mex" 
    ); 
} 

或者,如果你真的想设置一个现有的行为,您的特定值的值,你必须调用.Behaviors.Add(smb);前再次​​检查并host.AddServiceEndpoint前看看是否你处理的现有行为(当时再次加!),或者一个新的

+0

我试过你的代码,并且它失败了。我更新了上面的代码,使其成为完整的类和它的调用代码与您的编辑,它仍然失败:( –