2011-03-18 61 views
2

我正在使用Drew (with Source)提供的解决方案将统一注入到WCF服务中。该解决方案通过实例提供程序和行为在内部向WCF添加扩展点。我能够使它与我目前的项目一起工作。但是我用这种方法面临的问题是unity容器是通过读取扩展项目中配置文件中的xml动态初始化的。WCF with Unity,通过代码配置依赖关系

我与自动工厂使用统一,它不支持通过xml进行配置,并寻找一种方法来使用代码来注册依赖项,而不是服务项目中的xml。我如何获得统一容器

任何想法。

回答

2

我喜欢回答我自己的问题。

在当前的解决方案中,UnityInstanceProvider是硬编码的,所有我必须扩展初始化,以便可以覆盖。

public class UnityBehaviorExtensionElement : BehaviorExtensionElement 
{ 
    protected override object CreateBehavior() 
    { 
     return new UnityServiceBehavior() 
     { 
      InstanceProviderFunc = InstanceProviderFunc(), 
      ContainerName = this.ContainerName, 
      ContextChannelEnabled = this.ContextChannelEnabled, 
      InstanceContextEnabled = this.InstanceContextEnabled, 
      OperationContextEnabled = this.OperationContextEnabled, 
      ServiceHostBaseEnabled = this.ServiceHostBaseEnabled 
     }; 
    } 

    protected virtual Func<Type, string, UnityInstanceProvider> InstanceProviderFunc() 
    { 
     return (type, str) => new UnityInstanceProvider(type, str, UnityInstanceProvider.CreateUnityContainer); 
    } 
} 
    UnityServiceBehavior: IServiceBehavior 
    { 
    .... 
    public Func<Type, string, UnityInstanceProvider> InstanceProviderFunc; 


    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) 

    ... 

       foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers) 
       { 
        ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher; 
        if (channelDispatcher != null) 
        { 
         foreach (EndpointDispatcher endpointDispatcher in channelDispatcher.Endpoints) 
         { 
          endpointDispatcher.DispatchRuntime.InstanceProvider = 
           InstanceProviderFunc(serviceDescription.ServiceType, this.ContainerName); 
    .... 
    } 

现在我可以定义自己的BehaviorExtensionElement我的服务项目中,并覆盖InstanceProviderFunc

public class TestClientBehaviorExtensionElement:UnityBehaviorExtensionElement 
{ 
    protected override Func<Type, string, UnityInstanceProvider> InstanceProviderFunc() 
    { 
     return (type, str) => new UnityInstanceProvider(type, str, CreateUnityContainer); 
    } 

    ///<summary> 
    ///</summary> 
    ///<param name="containerName"></param> 
    ///<returns></returns> 
    public IUnityContainer CreateUnityContainer(string containerName) 
    { 
     IUnityContainer unityContainer = new UnityContainer(); 
     try 
     { 
      unityContainer.RegisterType<IOperationContextService, OperationContextService>(new UnityOperationContextLifetimeManager()); 
      ... 
     } 
     catch (Exception) 
     { 
      unityContainer.Dispose(); 
      throw; 
     } 

     return unityContainer; 
    }