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();
        }
    }

 

 

程序运行的效果:

 

 

代码下载

posted @ 2010-05-15 22:59  冬子哥  阅读(14042)  评论(12编辑  收藏  举报