客户端调用WCF服务可以通过添加服务引用的方式添加,这种方式使用起来比较简单,适合小项目使用。服务端与服务端的耦合较深,而且添加服务引用的方式生成一大堆臃肿的文件。本例探讨一种使用接口的方式使用WCF服务,克服通过服务引用方式产生的弊端。同时希望抛砖引玉,探讨更好的方式使用WCF。
1. 架构概述
解决方案
说明:
接口层:数字计算接口
服务实现层:实现数字计算接口
发布:同过IIS方式发布WCF服务
客户端:引用接口层,通过配置文件调用WCF服务
2. 接口层
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace Hbb0b0.WCF.Inteface
{
/// <summary>
/// 数学计算服务
/// </summary>
[ServiceContract]
public interface IMathService
{
/// <summary>
/// 相加服务
/// </summary>
/// <param name="p1"></param>
/// <param name="p2"></param>
/// <returns></returns>
[OperationContract]
int Add(int p1,int p2);
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace Hbb0b0.WCF.Inteface
{
/// <summary>
/// 数学计算服务
/// </summary>
[ServiceContract]
public interface IMathService
{
/// <summary>
/// 相加服务
/// </summary>
/// <param name="p1"></param>
/// <param name="p2"></param>
/// <returns></returns>
[OperationContract]
int Add(int p1,int p2);
}
}
3. 实现层
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Hbb0b0.WCF.Inteface;
namespace Hbb0b0.WCF.ServiceImp
{
/// <summary>
/// 计算服务实现
/// </summary>
public class MathService : IMathService
{
#region IMathService 成员
public int Add(int p1, int p2)
{
return p1 + p2;
}
#endregion
}
}
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using Hbb0b0.WCF.Inteface;
namespace Hbb0b0.WCF.ServiceImp
{
/// <summary>
/// 计算服务实现
/// </summary>
public class MathService : IMathService
{
#region IMathService 成员
public int Add(int p1, int p2)
{
return p1 + p2;
}
#endregion
}
}
4. 发布层
1. SVC
<%@ServiceHost language=c# Debug="true" Service="Hbb0b0.WCF.ServiceImp.MathService" %>
2. Web.Config
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="NewBinding0" />
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="MyServiceTypeBehaviors" name="Hbb0b0.WCF.ServiceImp.MathService">
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint address="http://localhost:1331/MathService.svc" binding="basicHttpBinding" bindingName="NewBinding0"
name="address" contract="Hbb0b0.WCF.Inteface.IMathService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors" >
<!-- 将下列元素添加到服务行为配置中。 -->
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="NewBinding0" />
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="MyServiceTypeBehaviors" name="Hbb0b0.WCF.ServiceImp.MathService">
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint address="http://localhost:1331/MathService.svc" binding="basicHttpBinding" bindingName="NewBinding0"
name="address" contract="Hbb0b0.WCF.Inteface.IMathService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors" >
<!-- 将下列元素添加到服务行为配置中。 -->
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
3. 调用层
1. Client
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Configuration;
using System.ServiceModel.Configuration;
using Hbb0b0.WCF.Inteface;
using System.Reflection;
using System.ServiceModel.Channels;
namespace MathServiceClient
{
class Program
{
/// <summary>
/// ServiceModel 属性
/// </summary>
static ServiceModelSectionGroup ServiceModelConfig;
/// <summary>
/// 构造函数中初始化ServiceModelConfig
/// </summary>
static Program()
{
if(ServiceModelConfig==null)
{
ServiceModelConfig = GetServiceModelSectionGroup();
}
}
static void Main(string[] args)
{
//不知道如何使用配置初始化Binding
//Binding binding = Assembly.GetCallingAssembly().CreateInstance(ServiceModelConfig.Bindings["NewBinding0"].BindingType.FullName) as Binding;
//初始化Endpoint
EndpointAddress point = new EndpointAddress(ServiceModelConfig.Client.Endpoints[0].Address);
//创建通道
IMathService service = ChannelFactory<IMathService>.CreateChannel(
new BasicHttpBinding () ,
point);
//调用
int result= service.Add(2, 3);
Console.WriteLine(string.Format("result={0}", result));
Console.Read();
}
/// <summary>
/// 获取ServiceModel配置信息
/// </summary>
/// <returns></returns>
static ServiceModelSectionGroup GetServiceModelSectionGroup()
{
Configuration conf = ConfigurationManager.OpenExeConfiguration(Assembly.GetEntryAssembly().Location);
ServiceModelSectionGroup svcmod = (ServiceModelSectionGroup)conf.GetSectionGroup("system.serviceModel");
return svcmod;
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Configuration;
using System.ServiceModel.Configuration;
using Hbb0b0.WCF.Inteface;
using System.Reflection;
using System.ServiceModel.Channels;
namespace MathServiceClient
{
class Program
{
/// <summary>
/// ServiceModel 属性
/// </summary>
static ServiceModelSectionGroup ServiceModelConfig;
/// <summary>
/// 构造函数中初始化ServiceModelConfig
/// </summary>
static Program()
{
if(ServiceModelConfig==null)
{
ServiceModelConfig = GetServiceModelSectionGroup();
}
}
static void Main(string[] args)
{
//不知道如何使用配置初始化Binding
//Binding binding = Assembly.GetCallingAssembly().CreateInstance(ServiceModelConfig.Bindings["NewBinding0"].BindingType.FullName) as Binding;
//初始化Endpoint
EndpointAddress point = new EndpointAddress(ServiceModelConfig.Client.Endpoints[0].Address);
//创建通道
IMathService service = ChannelFactory<IMathService>.CreateChannel(
new BasicHttpBinding () ,
point);
//调用
int result= service.Add(2, 3);
Console.WriteLine(string.Format("result={0}", result));
Console.Read();
}
/// <summary>
/// 获取ServiceModel配置信息
/// </summary>
/// <returns></returns>
static ServiceModelSectionGroup GetServiceModelSectionGroup()
{
Configuration conf = ConfigurationManager.OpenExeConfiguration(Assembly.GetEntryAssembly().Location);
ServiceModelSectionGroup svcmod = (ServiceModelSectionGroup)conf.GetSectionGroup("system.serviceModel");
return svcmod;
}
}
}
2. AppConfig
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<endpoint address="http://localhost:1331/MathService.svc" binding="basicHttpBinding"
contract="Hbb0b0.WCF.Inteface.IMathService" name="mathService" />
</client>
</system.serviceModel>
</configuration>
<configuration>
<system.serviceModel>
<client>
<endpoint address="http://localhost:1331/MathService.svc" binding="basicHttpBinding"
contract="Hbb0b0.WCF.Inteface.IMathService" name="mathService" />
</client>
</system.serviceModel>
</configuration>