wcf类库及宿主

说起wcf,一直以来总是直接创建wpf的应用程序,这样默认的宿主是IIS。如果想更换宿主,那么我们首先得创建wcf类库

这个类库会自动创建一个app.config文件。到最后部署的时候,把它移到宿主的项目下。看看IService1.cs:

 1 using Newtonsoft.Json;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 using System.Runtime.Serialization;
 6 using System.ServiceModel;
 7 using System.Text;
 8 
 9 namespace WcfServiceLibrary1
10 {
11     [ServiceContract]
12     public interface IService1
13     {
14         [OperationContract]
15         string GetDataUsingDataContract(CompositeType composite);
16 
17         // TODO: 在此添加您的服务操作
18     }
19 
20     // 可以将 XSD 文件添加到项目中。在生成项目后,可以通过命名空间“WcfServiceLibrary1.ContractType”直接使用其中定义的数据类型。
21     [DataContract]
22     public class CompositeType
23     {
24         [DataMember]
25         public string  UserName{set;get;}
26 
27         [DataMember]
28         public string FullName { set; get; }
29 
30         [DataMember]
31         public string Sex { set; get; }
32         [DataMember]
33         public string Email { set; get; }
34         [DataMember]
35         public string Depart { set; get; }
36         /// <summary>
37         /// 工作性质
38         /// </summary>
39         [DataMember]
40         public string WorkType { set; get; }
41         [DataMember]
42         public string Phone { set; get; }
43 
44         [DataMember]
45         public string ID { set; get; }
46 
47         public string ToJson()
48         {
49             return JsonConvert.SerializeObject(this);
50         }
51     }
52 }

该接口只提供一个方法,接收一个对象,返回string,再来看它的实现:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Runtime.Serialization;
 5 using System.ServiceModel;
 6 using System.Text;
 7 
 8 namespace WcfServiceLibrary1
 9 {
10     public class Service1 : IService1
11     {
12         public string GetDataUsingDataContract(CompositeType composite)
13         {
14             if (composite == null)
15             {
16                 throw new ArgumentNullException("composite");
17             }
18 
19             return "你好:" + composite.UserName;
20         }
21     }
22 }

然后,我们创建宿主程序。

一、wpf寄宿

 1 using System;
 2 using System.Collections.Generic;
 3 using System.IO;
 4 using System.Linq;
 5 using System.Net;
 6 using System.ServiceModel;
 7 using System.ServiceModel.Description;
 8 using System.Text;
 9 using System.Threading.Tasks;
10 using System.Windows;
11 using System.Windows.Controls;
12 using System.Windows.Data;
13 using System.Windows.Documents;
14 using System.Windows.Input;
15 using System.Windows.Media;
16 using System.Windows.Media.Imaging;
17 using System.Windows.Navigation;
18 using System.Windows.Shapes;
19 using WcfServiceLibrary1;
20 
21 namespace WpfInterface
22 {
23     public partial class MainWindow : Window
24     {
25         public MainWindow()
26         {
27             InitializeComponent();
28         }
29         private void Window_Loaded(object sender, RoutedEventArgs e)
30         {
31             WCFInit();
32         }
33 
34         private ServiceHost Host = null;
35         void WCFInit()
36         {
37             if (Host == null)
38             {
39                 Host = new ServiceHost(typeof(WcfServiceLibrary1.Service1));
40 
41                 Host.Open();
42 
43                 this.wcfService.Text = "wcf服务已启动";
44             }
45         }
46 
47         private void Window_Closed(object sender, EventArgs e)
48         {
49             if (Host != null)
50             {
51                 Host.Close();
52             }
53         }
54     }
55 }
ServiceHost来自 命名空间:System.ServiceModel,WcfServiceLibrary1.Service1来自类库,所以宿主项目必须引用 System.ServiceModel和wcf类库。39-41行,能够如此简洁地实例化ServiceHost,得益于App.config:
 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3 
 4   <appSettings>
 5     <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
 6   </appSettings>
 7   <system.web>
 8     <compilation debug="true" />
 9   </system.web>
10   <!-- 部署服务库项目时,必须将配置文件的内容添加到 
11   主机的 app.config 文件中。System.Configuration 不支持库的配置文件。-->
12   <system.serviceModel>
13 
14     <services>
15       <service name="WcfServiceLibrary1.Service1">
16         <host>
17           <baseAddresses>
18             <add baseAddress = "http://localhost:8003/Service1/" />
19           </baseAddresses>
20         </host>
21         <!-- Service Endpoints -->
22         <!-- 除非完全限定,否则地址将与上面提供的基址相关 -->
23         <endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary1.IService1">
24           <!-- 
25               部署时,应删除或替换下列标识元素,以反映
26              用来运行所部署服务的标识。删除之后,WCF 将
27               自动推断相应标识。
28           -->
29           <identity>
30             <dns value="localhost"/>
31           </identity>
32         </endpoint>
33         <!-- Metadata Endpoints -->
34         <!-- 元数据交换终结点供相应的服务用于向客户端做自我介绍。 -->
35         <!-- 此终结点不使用安全绑定,应在部署前确保其安全或将其删除-->
36         <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
37       </service>
38     </services>
39     <behaviors>
40       <serviceBehaviors>
41         <behavior>
42           <!-- 为避免泄漏元数据信息,
43           请在部署前将以下值设置为 false -->
44           <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
45           <!-- 要接收故障异常详细信息以进行调试,
46           请将以下值设置为 true。在部署前设置为 false 
47             以避免泄漏异常信息-->
48           <serviceDebug includeExceptionDetailInFaults="False" />
49         </behavior>
50       </serviceBehaviors>
51     </behaviors>
52   </system.serviceModel>
53 
54 </configuration>

wcf配置的三要素,简称ABC。

baseAddress:http://localhost:8003/Service1(地址)

binding:basicHttpBinding(通讯协议)

contract:WcfServiceLibrary1.IService1(契约)

针对这三要素,最复杂的和不好理解的就是bingding。binding背后隐藏了wcf的通讯机制,需要再单独研究。

二、word插件寄宿:

 1     private void ThisAddIn_Startup(object sender, System.EventArgs e)
 2         {
 3             try
 4             {
 5                 //创建宿主的基地址
 6                 Uri baseAddress = new Uri("http://localhost:8004/Service1");
 7 
 8                 //创建宿主
 9                 host = new ServiceHost(typeof(WcfServiceLibrary1.Service1), baseAddress);
10 
11                 host.AddServiceEndpoint(typeof(WcfServiceLibrary1.IService1), new WSHttpBinding(), "");
12 
13                 //将HttpGetEnabled属性设置为true
14                 ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
15                 smb.HttpGetEnabled = true;
16 
17                 //将行为添加到Behaviors中
18                 host.Description.Behaviors.Add(smb);
19 
20                 //打开宿主
21                 host.Open();
22                 Console.WriteLine("WCF中的HTTP监听已启动....");
23             }
24             catch (Exception ex)
25             {
26                 Console.WriteLine(ex.Message);
27             }
28             finally
29             {
30                 Console.WriteLine("word插件已启动");
31             }
32         }

由于word插件中不能使用配置文件,所以WCF的ABC三要素硬编码实现。

注意:wcf宿主程序启动时,必须以管理员的权限启动,否则会报错。

 

 





posted @ 2017-07-10 09:22  micDavid  阅读(1176)  评论(0编辑  收藏  举报