第三篇:试着去掉配置文件
通过配置文件来设置Host、Endpoint、Binding等是WCF中推荐的方法,这样可以使发布尽量灵活。其实配置文件中的值,最终还是要体现到代码中的,只不过这部分工作由底层帮你做了。我们今天来尝试去掉配置文件,用纯代码实现发布过程,同时加深一下对层次关系的理解。
1、服务端
在上回的基础上删掉App.config吧,然后把Main方法修改一下:
using System; using System.ServiceModel; namespace Server { class Program { static void Main(string[] args) { //定义两个基地址,一个用于http,一个用于tcp Uri httpAddress = new Uri("http://localhost:8080/wcf"); Uri tcpAddress = new Uri("net.tcp://localhost:8081/wcf"); //服务类型,注意同样是实现类的而不是契约接口的 Type serviceType = typeof(Server.DataProvider); //定义一个ServiceHost,与之前相比参数变了 using(ServiceHost host = new ServiceHost(serviceType, new Uri[] { httpAddress, tcpAddress })) { //定义一个basicHttpBinding,地址为空 Binding basicHttpBinding = new BasicHttpBinding(); string address = ""; //用上面定义的binding和address,创建endpoint host.AddServiceEndpoint(typeof(Server.IData), basicHttpBinding, address); //再来一个netTcpBinding Binding netTcpBinding = new NetTcpBinding(); address = ""; host.AddServiceEndpoint(typeof(Server.IData), netTcpBinding, address); //开始服务 host.Open(); Console.WriteLine("Service Running ..."); Console.ReadKey(); host.Close(); } } } }
如果我们把代码和之前的App.config对比着的地一下,就会发现元素是对应的。我们来整理一下目前为止出现的层级关系:
ServiceHost ├ ServiceType 实现类的类型 ├ Uri[] 基地址,对应config中的<baseAddresses> └ ServiceEndpoint[] 服务终结点,对应config中的多个<endpoint> ├ ServiceContract 服务契约,对应config中<endpoint>的contract属性 ├ Binding 绑定,对应config中<endpoint>的binding属性 └ EndpointAddress 终结点地址,对应config中<endpoint>的address属性 |
---|
2、客户端
同样可以删掉App.config了,代码改一下:
using System; using System.ServiceModel; using System.ServiceModel.Channels; namespace Client { class Program { static void Main(string[] args) { //定义绑定与服务地址 Binding httpBinding = new BasicHttpBinding(); EndpointAddress httpAddr = new EndpointAddress("http://localhost:8080/wcf"); //利用ChannelFactory创建一个IData的代理对象,指定binding与address,而不用配置文件中的 var proxy = new ChannelFactory<Server.IData>(httpBinding, httpAddr).CreateChannel(); //调用SayHello方法并关闭连接 Console.WriteLine(proxy.SayHello("WCF")); ((IChannel)proxy).Close(); //换TCP绑定试试 Binding tcpBinding = new NetTcpBinding(); EndpointAddress tcpAddr = new EndpointAddress("net.tcp://localhost:8081/wcf"); var proxy2 = new ChannelFactory<Server.IData>(httpBinding, httpAddr).CreateChannel(); Console.WriteLine(proxy2.SayHello("WCF")); ((IChannel)proxy2).Close(); } }
对照着上面,也来比对一下代码中现出的对象与App.config中的定义:
ClientEndpoint 客户端终结点,对应config中的<endpoint> ├ ServiceContract 服务契约,对应config中<endpoint>的contract属性 ├ Binding 绑定,对应config中<endpoint>的binding属性 └ EndpointAddress 地址,对应config中<endpoint>的address属性 |
---|
一般情况下,还是建议利用App.config来做发布的相关设定,不要写死代码。但如果只能在程序运行时动态获取发布的相关参数,那App.config就不行了。
OK,又前进了一点,下一篇会看看如何传递复杂对象。