WCF自寄宿
WCF很早就出现了,然而我感受到能够让新手重点去学习WCF而不是WebService是最近两年。我相信大部分人初步了解WCF的时候会很痛苦,尤其是生成代理类,以及配置的问题。我本人其实比较讨厌配置编程,但喜欢轻量配置,因此也一直研究如何自己定义配置节点,去让WCF服务识别,然后重量级ABC操作由编码来完成。下面,我将会提供一个我本人用于学习其他知识需要使用WCF时的开发模式,另外说明,为了更好的说明,我将提供的都是精简版本,并不适合用于测试生产的例子。
1.定义适合自己的配置
public class WCFServiceElement : ConfigurationElement
{
[ConfigurationProperty(name: "ServiceName", IsRequired = false)]
public string ServiceName
{
get
{
return (base["ServiceName"] as string);
}
set
{
base["ServiceName"] = value;
}
} [ConfigurationProperty(name: "ServiceAssembly", IsRequired = false)]
public string ServiceAssembly
{
get
{
return (base["ServiceAssembly"] as string);
}
set
{
base["ServiceAssembly"] = value;
}
} [ConfigurationProperty(name: "InterfaceServiceName", IsRequired = false)]
public string InterfaceServiceName
{
get
{
return (base["InterfaceServiceName"] as string);
}
set
{
base["InterfaceServiceName"] = value;
}
} [ConfigurationProperty(name: "InterfaceServiceAssembly", IsRequired = false)]
public string InterfaceServiceAssembly
{
get
{
return (base["InterfaceServiceAssembly"] as string);
}
set
{
base["InterfaceServiceAssembly"] = value;
}
} [ConfigurationProperty(name: "IPAddress", IsRequired = false)]
public string IPAddress
{
get
{
return (base["IPAddress"] as string);
}
set
{
base["IPAddress"] = value;
}
} [ConfigurationProperty(name: "Binding", IsRequired = false)]
public string Binding
{
get
{
return (base["Binding"] as string);
}
set
{
base["Binding"] = value;
}
}
}
public class WCFServicesElementCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
ConfigurationElement _element = new WCFServiceElement();
return _element;
} protected override object GetElementKey(ConfigurationElement element)
{
WCFServiceElement _element = (WCFServiceElement)element;
return _element.ServiceName;
} protected override string ElementName
{
get
{
return "WCFService";
}
} public override ConfigurationElementCollectionType CollectionType
{
get
{
return ConfigurationElementCollectionType.BasicMap;
}
}
}
public class WCFServiceSection : ConfigurationSection
{
[ConfigurationProperty(name: "", IsDefaultCollection = true, IsRequired = false)]
public WCFServicesElementCollection WCFServices
{
get
{
return (base[""] as WCFServicesElementCollection);
}
set
{
base[""] = value;
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="WCFServices" type="Basic.Configuration.WCFServiceSection,Basic.Data"/>
</configSections>
<WCFServices>
<WCFService ServiceName="AppManagementImplementation"
ServiceAssembly="Service.BackgroundManagement.Implementation"
InterfaceServiceName="IAppManagement"
InterfaceServiceAssembly="Service.BackgroundManagement.Interface"
IPAddress="http://192.168.1.4:8085/AppManagementService"
Binding="WSHttpBinding">
</WCFService>
</WCFServices>
</configuration>
这里注意的是configSections一定要放在第一行,这个倒是听让人无语的。当然配置可以用自己希望方式配置,我这里提供一个简单的思路。
2.定义适合自己的WCFServerConfigurationManagement
public abstract class WCFServerConfigurationManagement
{
private static HybridDictionary _Collection = new HybridDictionary(); public static void Register()
{
WCFServiceSection section = ConfigurationManager.GetSection("WCFServices") as WCFServiceSection;
if (null == section)
{
throw new NullReferenceException("未能识别WCFServices,请确认configSections配置节点");
} _Collection.Clear(); foreach (WCFServiceElement element in section.WCFServices)
{
Assembly assemblyInterfaceService = Assembly.Load(element.InterfaceServiceAssembly);
Assembly assemblyService = Assembly.Load(element.ServiceAssembly); Type typeInterface = assemblyInterfaceService.ExportedTypes.FirstOrDefault(type => type.Name.Equals(element.InterfaceServiceName));
Type typeImplement = assemblyService.ExportedTypes.FirstOrDefault(type => type.Name.Equals(element.ServiceName)); if (null == typeInterface && null == typeImplement)
{
throw new NullReferenceException("无法加载服务");
} ServiceHost _NewHost = new ServiceHost(typeImplement);
Binding binding = CreateBinding(element.Binding);
_NewHost.AddServiceEndpoint(typeInterface, binding, element.IPAddress); _NewHost.Opened += (sender, e) =>
{
#if DEBUG
Console.WriteLine($"服务:{element.ServiceName} 已经开启.");
#endif
};
_NewHost.Open();
}
} public static Binding CreateBinding(string bindingType)
{
Binding _Binding = default(Binding);
switch (bindingType)
{
case "BasicHttpBinding":
_Binding = new BasicHttpBinding();
break;
case "WSHttpBinding":
_Binding = new WSHttpBinding();
break;
case "WS2007HttpBinding":
_Binding = new WS2007HttpBinding();
break;
default:
throw new ArgumentNullException("根据接口名称无法匹配绑定类型");
} return _Binding;
}
}
这里主要用来根据配置动态配置WCF ServiceHost 和 Binding 的.然后再您的Custom Host 里面调用如下:
class Program
{
static void Main(string[] args)
{
WCFServerConfigurationManagement.Register(); Console.ReadLine();
}
}
3.定义适合自己的WCFClientConfigurationManagement
public abstract class WCFClientConfigurationManagement
{
private static HybridDictionary _Collection = new HybridDictionary(); public static void Register()
{
WCFServiceSection section = ConfigurationManager.GetSection("WCFServices") as WCFServiceSection;
if (null == section)
{
throw new NullReferenceException("未能识别WCFServices,请确认configSections配置节点");
} _Collection.Clear(); foreach (WCFServiceElement element in section.WCFServices)
{
_Collection.Add(element.InterfaceServiceName , element);
}
} public static Binding CreateBinding(string serviceName)
{
Binding _Binding = default(Binding);
WCFServiceElement element = _Collection[serviceName] as WCFServiceElement;
if (null == element)
{
Register();
element = _Collection[serviceName] as WCFServiceElement;
if (null == element)
{
throw new NullReferenceException("可能配置出现严重错误,根据接口名称无法获取配置文件信息.");
}
} switch (element.Binding)
{
case "BasicHttpBinding":
_Binding = new BasicHttpBinding();
break;
case "WSHttpBinding":
_Binding = new WSHttpBinding();
break;
case "WS2007HttpBinding":
_Binding = new WS2007HttpBinding();
break;
default:
throw new ArgumentNullException("根据接口名称无法匹配绑定类型");
} return _Binding;
} public static EndpointAddress CreateAddress(string serviceName)
{
WCFServiceElement element = _Collection[serviceName] as WCFServiceElement;
if (null == element)
{
Register();
element = _Collection[serviceName] as WCFServiceElement;
if (null == element)
{
throw new NullReferenceException("可能配置出现严重错误,根据接口名称无法获取配置文件信息.");
}
} EndpointAddress _Address = new EndpointAddress(element.IPAddress);
return _Address;
}
}
这里主要用来根据配置动态配置WCF Client 和 Binding 的。然后再您的客户端以及配置文件注册如下(我这里提供的是ASP.NET MVC 5 的环境):
public class MvcApplication : HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles); WCFClientConfigurationManagement.Register();
}
}
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="WCFServices" type="Basic.Configuration.WCFServiceSection,Basic.Data"/>
</configSections>
<WCFServices>
<WCFService InterfaceServiceName="IAppManagement"
IPAddress="http://192.168.1.4:8085/AppManagementService"
Binding="WSHttpBinding">
</WCFService>
</WCFServices>
</configuration>
4.定义适合自己的WCF ClientBase
public class WCFClient
{
public static TResult ClientInvoke<TChannel , TResult>(Func<TChannel , TResult> functionInvoke)
{
string _ServiceName = typeof(TChannel).Name;
Binding binding = WCFClientConfigurationManagement.CreateBinding(_ServiceName);
EndpointAddress address = WCFClientConfigurationManagement.CreateAddress(_ServiceName);
TChannel _channel = ChannelFactory<TChannel>.CreateChannel(binding, address);
TResult _Result = functionInvoke.Invoke(_channel);
return _Result;
}
}
以上交代完毕,当然提醒初步了解WCF的人IPAddress 配置也可以写*.svc地址,可以在自寄宿在Windows Service 里,也可以是IIS宿主环境。写到这里,希望这篇随笔能帮助到需要帮助的人,这也就是它的价值所在了。
WCF自寄宿的更多相关文章
- 创建WCF服务寄宿到IIS
一.WCF简介: Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Windows 通讯开发平台. 整合了原有的win ...
- WCF技术剖析之四:基于IIS的WCF服务寄宿(Hosting)实现揭秘
原文:WCF技术剖析之四:基于IIS的WCF服务寄宿(Hosting)实现揭秘 通过<再谈IIS与ASP.NET管道>的介绍,相信读者已经对IIS和ASP.NET的请求处理管道有了一个大致 ...
- WCF自寄宿实现Https绑定
一.WCF配置 1 Address 将服务端发布地址和客户端访问地址都配置为https开始的安全地址.参考如下. <add key="SrvUrl" value=" ...
- 关于WCF引用方式之WCF服务寄宿控制台
1.创建解决方案WCFService 依次添加四个项目,如上图,Client和Hosting为控制台应用程序,Service和Service.Interface均为类库. 2.引用关系 Service ...
- WCF服务寄宿应用程序
1.先创建一个WCF服务库 2.创建一个Console控制台,服务将寄宿在该应用程序上,该程序一旦关闭,服务将停止. 控制台代码: using System; using System.Collect ...
- WCF服务寄宿到IIS
一.WCF简介: Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Windows 通讯开发平台.整合了原有的wind ...
- WCF服务寄宿IIS与Windows服务 - C#/.NET
WCF是Windows平台下程序间通讯的应用程序框架.整合和 .net Remoting,WebService,Socket的机制,是用来开发windows平台上分布式开发的最佳选择.wcf程序的运行 ...
- WCF服务寄宿IIS与Windows服务
WCF是Windows平台下程序间通讯的应用程序框架.整合和 .net Remoting,WebService,Socket的机制,是用来开发windows平台上分布式开发的最佳选择.wcf程序的 ...
- 将使用netTcp绑定的WCF服务寄宿到IIS7上全记录 (这文章也不错)
原文地址:http://www.cnblogs.com/wengyuli/archive/2010/11/22/wcf-tcp-host-to-iis.html 摘要 在项目开发中,我们可能会适时的选 ...
随机推荐
- xamarin UWP证书问题汇总
打算开发一个软件使用rsa加密的东西,所以有用到数字证书这块,最近遇到些问题, 问题一:使用如下代码添加数字证书后,在证书管理器的当前用户和本地计算机下都找不到这张证书. using (X509Sto ...
- WCF学习之旅—WCF第二个示例(六)
第五步,创建数据服务 在“解决方案资源管理器”中,使用鼠标左键选中“SCF.WcfService”项目,然后在菜单栏上,依次选择“项目”.“添加新项”. 在“添加新项”对话框中,选择“Web”节点,然 ...
- 删除 Windows 旧 OS 加载器
装过多个系统,然后又删除掉了,系统启动引导时,又把以前的废弃的系统引导给带了出来,试过多种方式,以下方法是最好的. 开始->运行->cmd bcdedit /v 查看要删除的"W ...
- 【商业源码】生日大放送-Newlife商业源码分享
今天是农历六月二十三,是@大石头的生日,记得每年生日都会有很劲爆的重量级源码送出,今天Newlife群和论坛又一次疯狂了,吃水不忘挖井人,好的东西肯定要拿到博客园分享.Newlife组件信息: 论坛: ...
- MySQL学习笔记五:数据类型
MySQL支持多种数据类型,大致可以分为数值,日期/时间和字符类型. 数值类型 MySQL支持所有标准SQL数值数据类型,包括严格数值数据类型(INTEGER.SMALLINT.DECIMAL和NUM ...
- react+redux教程(四)undo、devtools、router
上节课,我们介绍了一些es6的新语法:react+redux教程(三)reduce().filter().map().some().every()....展开属性 今天我们通过解读redux-undo ...
- MVC, MVP, MVVM比较以及区别(下)
上一篇得到大家的关注,非常感谢.一些朋友评论中,希望快点出下一篇.由于自己对于这些模式的理解也是有限,所以这一篇来得迟了一些.对于这些模式的比较,是结合自己的理解,一些地方不一定准确,但是只有亮出自己 ...
- Java多线程系列--“JUC锁”01之 框架
本章,我们介绍锁的架构:后面的章节将会对它们逐个进行分析介绍.目录如下:01. Java多线程系列--“JUC锁”01之 框架02. Java多线程系列--“JUC锁”02之 互斥锁Reentrant ...
- iOS对象属性详解
oc对象的一些属性: retain,strong, copy,weak,assign,readonly, readwrite, unsafe_unretained 下面来分别讲讲各自的作用和区别: r ...
- Javascript的无new构建
看jquery源代码第一步的时候,对于jquery对象的创建就看的云里雾里,琢磨半天终于有点感觉了,在此记录下 第一种方式: var A = function(){ return A.prototyp ...