zoukankan      html  css  js  c++  java
  • Spring.NET学习笔记22——整合WCF(应用篇) Level 200

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

     

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

      

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

    Contract
        [ServiceContract]
        
    public interface IWcfContract
        {
            [OperationContract]
            
    string GetData(int value);
        }

        
    public class ImplementService : IWcfContract
        {
            
    public string GetData(int value)
            {
                
    return "你输入的是:" + value;
            }
        }

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

    <object id="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文件

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

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

      配置web.config文件

    代码
    <system.serviceModel>
            
    <services>
                
    <service name="WcfServer" behaviorConfiguration="WcfServerBehavior">
                    
    <!-- Service Endpoints -->
                    
    <endpoint address="" binding="wsHttpBinding" contract="IContract.IWcfContract"/>
                    
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
                
    </service>
            
    </services>
            
    <behaviors>
                
    <serviceBehaviors>
                    
    <behavior name="WcfServerBehavior">
                        
    <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点-->
                        
    <serviceMetadata httpGetEnabled="true"/>
                        
    <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息-->
                        
    <serviceDebug includeExceptionDetailInFaults="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对象的配置

      <object id="WcfServerHost" type="Spring.ServiceModel.Activation.ServiceHostFactoryObject, Spring.Services">
        
    <property name="TargetName" value="WcfServer" />
      
    </object>

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

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

    代码
    <system.serviceModel>

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

        
        
    <services>

          
    <service name="WcfServer" behaviorConfiguration="WcfServerBehavior">
            
    <endpoint binding="netTcpBinding" contract="IContract.IWcfContract"
                      bindingConfiguration
    ="ServerBinding"
                      address
    ="net.tcp://localhost:3286/App/Server/"/>
            
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
            
    <host>
              
    <baseAddresses>
                
    <add baseAddress="http://localhost:3285/App/Server/"/>
              
    </baseAddresses>
            
    </host>
          
    </service>
        
        
    </services>
       
        
    <bindings>
          
          
    <netTcpBinding>
            
    <binding name="ServerBinding">
              
    <security mode="None">
                
    <transport clientCredentialType="None" />
                
    <message clientCredentialType="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宿主的信道工厂-->
      
    <object id="WebChannelFactory"
          type
    ="System.ServiceModel.ChannelFactory&lt;IContract.IWcfContract>, System.ServiceModel">
        
    <constructor-arg name="endpointConfigurationName" value="WSHttpBinding_IContract" />
      
    </object>

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

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

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

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

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

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

    客户端中调用WCF代理类

    Program
    class Program
        {
            
    static void Main(string[] args)
            {
                IApplicationContext cxt 
    = ContextRegistry.GetContext();
                
                
    //调用web宿主
                IWcfContract webProxy = (IWcfContract)cxt.GetObject("WebProxy");
                Console.WriteLine(webProxy.GetData(
    1));


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


                Console.ReadLine();
            }
        }

    程序运行的效果:

    代码下载

  • 相关阅读:
    BZOJ 1412: [ZJOI2009]狼和羊的故事
    Bzoj 2443: [Usaco2011 Open]奇数度数
    Bzoj 1101: [POI2007]Zap
    BZOJ 2186: [Sdoi2008]沙拉公主的困惑
    BZOJ 4804: 欧拉心算 欧拉函数
    Luogu P3121 [USACO15FEB]审查(黄金)Censoring (Gold)
    Luogu P3000 [USACO10DEC]牛的健美操Cow Calisthenics
    BZOJ 2060: [Usaco2010 Nov]Visiting Cows 拜访奶牛
    BZOJ 3297: [USACO2011 Open]forgot
    BZOJ 2456: mode
  • 原文地址:https://www.cnblogs.com/GoodHelper/p/SpringNet_Wcf.html
Copyright © 2011-2022 走看看