1. 程式人生 > >WCF一個Host實現多契約服務

WCF一個Host實現多契約服務

因為最初錯誤的理解了Contract與Service的關係,把每個業務定義了相應的Contract與Service並將對應的Service一一繼承相應的Contract,因為在WCF每個host只能提供一個Service所以導致,當你的服務很多的時候你要定義N多個host
看下面演示提供User(使用者)和Order(訂單)兩個服務:

開啟多個host程式碼:

ServiceHost host1 = new ServiceHost(typeof(UserService)); 
host1.Open();
ServiceHost host2 = new ServiceHost(typeof(OrderService)); 
host2.Open();

開啟多個host配置

<system.serviceModel>
    <services>
      <service name="Wcf.Services.UserService">
        <endpoint address="net.tcp://localhost:8001/UserService" binding="netTcpBinding"  contract="Wcf.Contract.IUserService" >
        </endpoint>
      </service>
      <service name="Wcf.Services.OrderService">
        <endpoint address="net.tcp://localhost:8001/OrderService"  binding="netTcpBinding" contract="Wcf.Contract.IOrderService" >
        </endpoint>
      </service>
    </services>
</system.serviceModel>

參考:
WCF中ServiceHost能不能host多個服務?
http://www.cnblogs.com/vivid-stanley/archive/2007/02/21/653280.html
Host多個WCF服務(Self-host)
http://www.cnblogs.com/levinknight/archive/2007/05/25/760176.html

後來發現Service是可以和業務型別沒關係的,它僅用來表示當前host能提供的服務,不要理解Service要根據不同的業務型別來切分,Contract才是和業務型別有關係的原則上要按照業務型別來切分。然後其實WCF並不推薦在應用程式域中建立多個ServiceHost例項。如果要託管多個服務,完全可以在一個host中通過多個Endpoint公開多個WCF服務的辦法來實現,而每個Endpoint都可以對應相應的Contract。

User契約程式碼:

namespace Wcf.Contract
{
    [ServiceContract]
    public interface IUserService
    {
        [OperationContract]
        void Edit();
    }
}

Order契約程式碼:

namespace Wcf.Contract
{
    [ServiceContract]
    public interface IOrderService
    {
        [OperationContract]
        void Add();
    }
}

Service程式碼:讓所有功能在一個Service上實現

namespace Wcf.Services
{
    public class MallService : IUserService, IOrderService
    {

    
        public void Add()
        {
            throw new NotImplementedException();
        }


        void Edit()
        {
            throw new NotImplementedException();
        }


    }
}

當然這裡可以使用 partial 關鍵字 把程式碼放在不同的檔案上,來達到物理上的切分比如:
檔案UserService.cs
public partial class MallService : IUserService
檔案 OrderService.cs
public partial class MallService : IOrderService

host程式碼

namespace Wcf.Host
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(Wcf.Services.MallService)))
            {
                host.Open();
                Console.Read();
            }
        }
    }
}

配置檔案:在一個service上定義多個endpoint使用不同的契約介面

<system.serviceModel>
    <services>
      <service name="Wcf.Services.MallService" behaviorConfiguration="MallServiceBehaviors" >      
        <endpoint  address="" contract="Wcf.Contract.IUserService" binding="basicHttpBinding"></endpoint>
        <endpoint  address="" contract="Wcf.Contract.IOrderService" binding="basicHttpBinding"></endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8899/MallService%22/>
          </baseAddresses>
        </host>
      </service>
      
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MallServiceBehaviors" >
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

  </system.serviceModel>

客戶端程式碼:客戶端可以根據不同endpoint的契約實現不同的類

namespace Wcf.Test
{
    class Program
    {
        static void Main(string[] args)
        {
            UserServiceClient user = new UserServiceClient();
            user.Edit();

            OrderServiceClient order = new OrderServiceClient();
            order.Add();
        }
    }
}

以後如果要對WCF應用程式擴充套件只需定義契約 然後partial class MallService : 契約介面 實現程式碼, 並在host的在配置檔案中加入 相應的 endpoint 即可