Spring.NET学习笔记22——整合WCF(应用篇) Level 200


  Spring.NETWCF(Windows Communication Foundation)有很好的支持,Spring.Services程序集下封装了创建和调用WCF的方法。以往,我们使用svc文件来承载WCF;使用自动生产的代理来调用服务。这样便对产生了诸多依赖。而使用Spring.NET则会令应用程序得到良好的改善。

  让我们从实例中学习今天的内容:

  

  首先创建服务契约和其实现

Contract
[ServiceContract]
publicinterfaceIWcfContract
{
[OperationContract]
stringGetData(intvalue);
}

publicclassImplementService:IWcfContract
{
publicstringGetData(intvalue)
{
return"你输入的是:"+value;
}
}

  把服务契约的实现类加入Spring.NET中管理

<objectid="WcfServer"type="WcfSevice.ImplementService,WcfSevice"/>

  创建一个WCF的WCF项目,并引用Common.Logging.dll、Spring.Core.dll、Spring.Data.dll、Spring.Web.dll、Spring.Services.dll(在Spring.NET库下的3.0文件夹里)

  Spring.ServiceModel.Activation.ServiceHostFactory类继承自System.ServiceModel.Activation.ServiceHostFactory,用于在BS架构中承载WCF

  建立svc文件

<%@ServiceHostLanguage="C#"Debug="true"Service="WcfServer"Factory="Spring.ServiceModel.Activation.ServiceHostFactory"%>

指定Service属性为服务契约的实现类(WcfServer)

  配置web.config文件

代码
<system.serviceModel>
<services>
<servicename="WcfServer"behaviorConfiguration="WcfServerBehavior">
<!--ServiceEndpoints-->
<endpointaddress=""binding="wsHttpBinding"contract="IContract.IWcfContract"/>
<endpointaddress="mex"binding="mexHttpBinding"contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behaviorname="WcfServerBehavior">
<!--为避免泄漏元数据信息,请在部署前将以下值设置为false并删除上面的元数据终结点-->
<serviceMetadatahttpGetEnabled="true"/>
<!--要接收故障异常详细信息以进行调试,请将以下值设置为true。在部署前设置为false以避免泄漏异常信息-->
<serviceDebugincludeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

指定Service节点的name属性为刚才配置的Spring.NET对象(WcfServer)。

在Global的Application_Start方法中实例化Spring.NET对象(Spring.Context.Support.ContextRegistry.GetContext();)

这样WEB宿主的WCF就搭建成功了。

而在winform或者控制台等程序中无法使用svc文件来承载WCF,但这一点被Spring.NET开发团队考虑到了。Spring.Services程序集下的Spring.ServiceModel.Activation.ServiceHostFactoryObject则是用于非WEB环境的WCF创建。

我们以控制台程序为例,来讲解在非WEB环境的WCF创建:

在控制台程序中创建一项Spring.NET对象的配置

<objectid="WcfServerHost"type="Spring.ServiceModel.Activation.ServiceHostFactoryObject,Spring.Services">
<propertyname="TargetName"value="WcfServer"/>
</object>

指明TargetName属性为实现服务契约的Spring.NET对象(WcfServer)

配置app.config文件,这里为了区别WEB环境,我使用netTcpBinding的绑定方式。

代码
<system.serviceModel>

<behaviors>
<serviceBehaviors>
<behaviorname="WcfServerBehavior">
<!--为避免泄漏元数据信息,请在部署前将以下值设置为false并删除上面的元数据终结点-->
<serviceMetadatahttpGetEnabled="true"/>
<!--要接收故障异常详细信息以进行调试,请将以下值设置为true。在部署前设置为false以避免泄漏异常信息-->
<serviceDebugincludeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>


<services>

<servicename="WcfServer"behaviorConfiguration="WcfServerBehavior">
<endpointbinding="netTcpBinding"contract="IContract.IWcfContract"
bindingConfiguration
="ServerBinding"
address
="net.tcp://localhost:3286/App/Server/"/>
<endpointaddress="mex"binding="mexHttpBinding"contract="IMetadataExchange"/>
<host>
<baseAddresses>
<addbaseAddress="http://localhost:3285/App/Server/"/>
</baseAddresses>
</host>
</service>

</services>

<bindings>

<netTcpBinding>
<bindingname="ServerBinding">
<securitymode="None">
<transportclientCredentialType="None"/>
<messageclientCredentialType="None"/>
</security>
</binding>
</netTcpBinding>

</bindings>

</system.serviceModel>

指明baseAddress是为了便于生成WCF的代理类。

最后在控制台程序的Main方法中实例化Spring.NET容器,这样一个以控制台为宿主的WCF环境便搭建成功了。

  然而对于调用WCF,我们通常使用“添加服务应用”的方式来生成WCF的代理类。这样,在整个项目都使用Spring.NET框架的环境下,很难管理WCF的代理类。

为了让Spring.NET来管理WCF的代理类,我们需要配置System.ServiceModel.ChannelFactory<T>这个泛型类,再配置代理类中的factory-method属性。
至于System.ServiceModel.ChannelFactory<T>类,是用来创建和管理客户端用来将消息发送到服务终结点的通道,这里不细讲,请查看MSDN。

Client
<!--创建web宿主的信道工厂-->
<objectid="WebChannelFactory"
type
="System.ServiceModel.ChannelFactory&lt;IContract.IWcfContract>,System.ServiceModel">
<constructor-argname="endpointConfigurationName"value="WSHttpBinding_IContract"/>
</object>

<!--调用web宿主的代理类-->
<objectid="WebProxy"
type
="IContract.IWcfContract,IContract"
factory-object
="WebChannelFactory"
factory-method
="CreateChannel"singleton="false"/>

<!--创建app宿主的信道工厂-->
<objectid="AppChannelFactory"
type
="System.ServiceModel.ChannelFactory&lt;IContract.IWcfContract>,System.ServiceModel">
<constructor-argname="endpointConfigurationName"value="NetTcpBinding_IContract"/>
</object>

<!--调用app宿主的代理类-->
<objectid="AppProxy"
type
="IContract.IWcfContract,IContract"
factory-object
="AppChannelFactory"
factory-method
="CreateChannel"/>

注意的是System.ServiceModel.ChannelFactory<T>的构造函数中需要指明endpointConfigurationName属性为endpoint的name属性

app.config
<client>
<endpointaddress="http://localhost:3287/WebHost.svc"binding="wsHttpBinding"
bindingConfiguration
="WSHttpBinding_IContract"contract="IContract.IWcfContract"
name
="WSHttpBinding_IContract"/>

<endpointaddress="net.tcp://localhost:3286/App/Server/"binding="netTcpBinding"
bindingConfiguration
="NetTcpBinding_IContract"contract="IContract.IWcfContract"
name
="NetTcpBinding_IContract"/>
</client>

客户端中调用WCF代理类

Program
classProgram
{
staticvoidMain(string[]args)
{
IApplicationContextcxt
=ContextRegistry.GetContext();

//调用web宿主
IWcfContractwebProxy=(IWcfContract)cxt.GetObject("WebProxy");
Console.WriteLine(webProxy.GetData(
1));


//调用app宿主
IWcfContractappProxy=(IWcfContract)cxt.GetObject("AppProxy");
Console.WriteLine(appProxy.GetData(
2));


Console.ReadLine();
}
}

程序运行的效果:

代码下载

优质内容筛选与推荐>>
1、Docker 简介
2、UIButton如何正确调整imageView及titleLabel的位置
3、Educational Codeforces Round 32 ABC
4、101. Symmetric Tree
5、吴裕雄--天生自然 物理学习与探索笔记:功与能


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn