实现英文,实现WCF和Unity 的集成

如果您有疑问或建议,请进入技术讨论区交流 >>>
     Artech 已经写过一篇[原创]WCF后续之旅(7):通过WCF Extension实现和Enterprise Library Unity Container的集成,在这个解决方案中Unity的侵入性有点强,本文介绍一种具有更少的侵入性的解决方案。
  
  第一步:创建一个自定义的InstanceProvider 来处理WCF服务。
  
  InstanceProvider就是用于创建或者提供service instance的。除了提供service instance的创建者或者提供者的身份外,InstanceProvider还用于service instance的释放和回收。所有的IntanceProvider实现了System.ServiceModel.Dispatcher.IInstanceProvider 接口:
  
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using Microsoft.Practices.Unity;
  using System.ServiceModel.Dispatcher;
  using System.ServiceModel;
  using System.ServiceModel.Channels;
  
  namespace Tencent.OA.Framework.ServiceModel
  {
   public class UnityInstanceProvider : IInstanceProvider
   {
  
   public UnityContainer Container { set; get; }
   public Type ServiceType { set; get; }
  
   public UnityInstanceProvider()
   : this(null)
   {
  
   }
  
   public UnityInstanceProvider(Type type)
   {
  
   ServiceType = type;
   Container = new UnityContainer();
  
   }
  
   #region IInstanceProvider Members
  
   public object GetInstance(InstanceContext instanceContext, Message message)
   {
   return Container.Resolve(ServiceType);
   }
  
   public object GetInstance(InstanceContext instanceContext)
   {
   return GetInstance(instanceContext, null);
   }
  
   public void ReleaseInstance(InstanceContext instanceContext, object instance)
   {
  
   }
  
   #endregion
  
   }
  }
  
  可以看到GetInstance方法用来获取服务实例,通过Unity的Resolve方法解析。
  
  第二步:创建UnityInstanceProvider对应的Behavior
  
  第一步已经创建了自定义的UnityInstanceProvider,现在需要在运行时插入我们这个新的Provider,这项工作可以通过IServiceProvider(定义一种检索服务对象的机制,服务对象是为其他对象提供自定义支持的对象)来完成。
  
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.ServiceModel.Dispatcher;
  using System.ServiceModel.Description;
  using System.ServiceModel;
  using System.Collections.ObjectModel;
  using System.ServiceModel.Channels;
  using Microsoft.Practices.Unity;
  
  namespace Tencent.OA.Framework.ServiceModel
  {
   public class UnityServiceBehavior : IServiceBehavior
   {
  
   public UnityInstanceProvider InstanceProvider
  
   { get; set; }
  
   private ServiceHost serviceHost = null;
  
   public UnityServiceBehavior()
   {
  
   InstanceProvider = new UnityInstanceProvider();
  
   }
  
   public UnityServiceBehavior(UnityContainer unity)
   {
   InstanceProvider = new UnityInstanceProvider();
   InstanceProvider.Container = unity;
  
   }
  
   public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
   {
  
   foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
   {
  
   ChannelDispatcher cd = cdb as ChannelDispatcher;
  
   if (cd != null)
   {
  
   foreach (EndpointDispatcher ed in cd.Endpoints)
   {
   InstanceProvider.ServiceType = serviceDescription.ServiceType;
   ed.DispatchRuntime.InstanceProvider = InstanceProvider;
   }
  
   }
  
   }
  
   }
  
   public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
   { }
  
   public void AddBindingParameters(ServiceDescription serviceDescription,ServiceHostBase serviceHostBase,Collection<ServiceEndpoint> endpoints,
   BindingParameterCollection bindingParameters)
   {
  
   }
  
   }
  
  }
  
  当调用ApplyDispatchBehaviour,代码通过循环收集在我们的项目Endpoints,并传递给相应的服务类型的InstanceProvider。
  
  第三步:创建自定义的增加新的Behavior的 Service Host
  
  ServiceHost 提供了基本的“加载服务,配置endpoints,应用安全设置以及启动监听请求”机制。通过自定义一个ServiceHost将我们自己的Behavior添加进去。
  
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.ServiceModel;
  using Microsoft.Practices.Unity;
  
  namespace Tencent.OA.Framework.ServiceModel
  {
   public class UnityServiceHost : ServiceHost
   {
  
   public UnityContainer Container { set; get; }
  
   public UnityServiceHost()
   : base()
   {
   Container = new UnityContainer();
   }
  
   public UnityServiceHost(Type serviceType, params Uri[] baseAddresses)
   : base(serviceType, baseAddresses)
   {
  
   Container = new UnityContainer();
  
   }
  
   protected override void _disibledevent=>   this.Description.Behaviors.Add(new UnityServiceBehavior(Container));
  
   base.OnOpening();
   }
  
   }
  
  }
  
  当Service Host启动的时候,它就会检查我们的UnityServiceBehavior是否已经添加到Behaviors里面,如果没有就把它加入到Behaviors集合。
  
  第四步:创建自定义的ServiceHostFactory
  
  如果只是承载在Console Application、Windows Service或者其他非Web应用程序,我们的工作已经完成了。但在Web的.svc中,ServiceHost是动态创建的,没有显示的指定ServiceHost的Factory,那它在默认情况下是使用ServiceHostFactory的,而ServiceHostFactory产生的是ServiceHost对象,想要使用我们上一步中自定义的UnityServiceHost ,需要实现一个自定义的ServcieHostFactory,实现代码非常简单:
  
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using Microsoft.Practices.Unity.Configuration;
  using Microsoft.Practices.Unity;
  using System.ServiceModel.Activation;
  using System.ServiceModel;
  using System.Configuration;
  
  namespace Tencent.OA.Framework.ServiceModel
  {
   public class UnityServiceHostFactory : ServiceHostFactory
   {
  
   protected override ServiceHost CreateServiceHost(
  
   Type serviceType, Uri[] baseAddresses)
   {
  
   UnityServiceHost serviceHost = new UnityServiceHost(serviceType, baseAddresses);
   UnityContainer container = new UnityContainer();
   serviceHost.Container = container;
   //configure container
   UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
   section.Containers.Default.Configure(serviceHost.Container);
   return serviceHost;
  
   }
  
   }
  
  }  
Tags:  收付实现制 实现理想 实现目标 实现英文

延伸阅读

最新评论

发表评论