在 Unity Container 中注册 WCF 服务

Posted

技术标签:

【中文标题】在 Unity Container 中注册 WCF 服务【英文标题】:Registering WCF service in Unity Container 【发布时间】:2012-03-06 19:18:48 【问题描述】:

我有一个托管在 Windows 服务中的 wcf 服务库。我需要拦截对 服务方法。对于这种情况,建议将 WCF 注册到 Unity 容器中,如此链接所示

http://weblogs.asp.net/fabio/archive/2009/03/24/inversion-of-control-with-wcf-and-unity.aspx

我正在尝试通过来自 Codeplex 的 Unity.WCF 程序集实现类似的方法。我无法理解将容器配置或引导程序放在 wcf 服务库(或 Windows 服务)中的什么位置。没有提供固体样品(相对于溶液)。

我的 Windows 服务主机

    private UnityServiceHost _serviceHost = null;
    private readonly UnityContainer _container;


    public Service() 
        InitializeComponent();
        _container = new UnityContainer();
        _container.AddNewExtension<Interception>();
        _container.RegisterType<ISecurityRepository, SecurityRepository>();
        _container.Configure<Interception>().SetDefaultInterceptorFor<ISecurityRepository>(new TransparentProxyInterceptor());
    

    protected override void OnStart(string[] args) 

        //SecurityService
        if (_serviceHost != null) 

            _serviceHost.Close();
         else 
            _serviceHost = new UnityServiceHost(_container, typeof(SecurityRepository));
            _serviceHost.Open();
        

    

    protected override void OnStop() 

        //SecurityService
        if (_serviceHost != null) 

            _serviceHost.Close();
            _serviceHost = null;
        
    

我的服务合同

[ServiceContract(SessionMode = SessionMode.Required)]
public interface ISecurityRepository


    [OperationContract(IsInitiating = true)]
    IList<vNavigationTree> GetNavigationTree(string ticket);

    [OperationContract(IsInitiating = true)]
    string GetSessionGuid(string userName, string IP, string machineName);

在这种情况下,拦截器似乎不起作用。简而言之,我需要的是一个示例项目,其中 WCF 服务注册到 DI 容器并拦截了服务方法。

【问题讨论】:

【参考方案1】:

我将尝试更明确地解释我尝试做的事情以及我是如何做到的。我有一个 WPF 应用程序通过 WCF 与数据库通信,这意味着我的应用程序大致分为两部分:客户端和服务器端 (WCF)。我已通过 PRISM 提供的 UnityBootStrapper 将客户端包装到 Unity 容器中。我还需要将服务器端包装到另一个 Unity 容器中,以使 Unity 解决服务器端依赖项。

Unity.WCF(可作为Nuget 包提供)解决了我的问题,它提供了可以代替 ServiceHost 使用的 UnityServiceHost 类。我猜这个包是按照这篇文章解释的方式创建的:

http://weblogs.asp.net/fabio/archive/2009/03/24/inversion-of-control-with-wcf-and-unity.aspx

【讨论】:

【参考方案2】:

您需要做的是利用统一拦截管道。

Unity 提供了内置的策略注入行为来方便 aop 的实现。策略注入行为通过使用调用处理程序和基于每个方法的匹配规则将某些功能附加或注入特定方法。

一个。从 ICallhandler 的自定义接口开始。

>>    public interface ILogAttributeHandler : ICallHandler
>>    
>>    
>>

b.为您的处理程序添加您的实现。这是您在方法被拦截时要应用的建议。

>>    public class ActivityAttributeHandler : ILogAttributeHandler
>>    
>>    public ActivityAttributeHandler(string activityType)
>>    
>>    ActivityType = activityType;
>>    

>>    private string ActivityType  get; set; 
>>    public int Order  get; set; 

>>    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
>>    
 >>           //// Invoke the handler
>>            IMethodReturn output = getNext()(input, getNext);

>>            //// Perform post-processing task
>>            var agent = output.ReturnValue as Agent;

>>            if (agent != null)
>>            
>>               //// do work here 
>>            

>>            return getNext()(input, getNext);
>>        

c。创建您的自定义属性,这将用作程序中的切入点。

>>  [AttributeUsage(AttributeTargets.Method)]
>>   public class ActivityAttribute : HandlerAttribute
>>    
>>        private readonly string _activityName;

 >>       public ActivityAttribute(string activityName)
>>        
>>            _activityName = activityName;
>>        
>> 
>>       public override ICallHandler CreateHandler(IUnityContainer container)
>>      
>>  return null;
>>

d。现在你剩下的就是在你的统一配置中配置拦截,并将属性添加到你想要被拦截的服务接口操作中。

>  container
>                 .RegisterType<ILogAttributeHandler, LogAttributeHandler>()
>                 .AddNewExtension<Interception>()
>                 .Configure<Interception>()
>                .SetInterceptorFor<ISecurityRepository>("SecurityRepository", new
> InterfaceInterceptor());

e。将属性应用于您的界面操作

>>public interface ISecurityRepository 
>> 
>>    [OperationContract(IsInitiating = true)]
>>    [Activity("Logon")]
>>    IList<vNavigationTree> GetNavigationTree(string ticket)
>>

【讨论】:

以上是关于在 Unity Container 中注册 WCF 服务的主要内容,如果未能解决你的问题,请参考以下文章

在 WCF 中使用 Unity 将依赖项注入到属性中

Unity DI Container RegisterType 方法中断从 v5.8.x 到 v5.9.x 的更改

Unity 依赖注入

Unity IoC Container创建对象过程

WCF:指定的注册表项在 base.Channel 调用中不存在

具有逆变类型参数和 Unity 容器的泛型