如何注入到dependencis与WCF简单的喷油器属性 [英] How to inject dependencis into WCF Attribute with Simple Injector

查看:338
本文介绍了如何注入到dependencis与WCF简单的喷油器属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一大堆的WCF服务与REST和SOAP的作品。我创建了一个WCF属性谁检查,如果当前的HttpContext存在,如果存在,它使用Cookie身份验证,它使用自定义的WCF身份验证办法了。

I have a bunch of WCF services that works with REST and SOAP. I have created an WCF attribute who checks if the current httpcontext exists, if exists it use cookie authentication, other way it use custom WCF authentication.

我的属性看起来是这样的:

My attribute looks like this:

Public Class AuthRequired
    Inherits Attribute
    Implements IOperationBehavior, IParameterInspector

    Public Sub AddBindingParameters(operationDescription As OperationDescription, bindingParameters As Channels.BindingParameterCollection) Implements IOperationBehavior.AddBindingParameters

    End Sub

    Public Sub ApplyClientBehavior(operationDescription As OperationDescription, clientOperation As ClientOperation) Implements IOperationBehavior.ApplyClientBehavior

    End Sub

    Public Sub ApplyDispatchBehavior(operationDescription As OperationDescription, dispatchOperation As DispatchOperation) Implements IOperationBehavior.ApplyDispatchBehavior
        dispatchOperation.ParameterInspectors.Add(Me)
    End Sub

    Public Sub Validate(operationDescription As OperationDescription) Implements IOperationBehavior.Validate

    End Sub

    Public Sub AfterCall(operationName As String, outputs() As Object, returnValue As Object, correlationState As Object) Implements IParameterInspector.AfterCall

    End Sub

    Public Function BeforeCall(operationName As String, inputs() As Object) As Object Implements IParameterInspector.BeforeCall
        ' IDS is the custom authentication service.
        If IDS.Usuario Is Nothing Then
            If HttpContext.Current Is Nothing Then
                Throw New SecurityException("Las credenciales no son válidas para esta operación o no fueron provistas.")
            Else
                Throw New WebFaultException(Of String)("ACCESO DENEGADO. REVISE SUS CREDENCIALES.", Net.HttpStatusCode.Forbidden)
            End If
        End If
    End Function
End Class

所以,我的问题是我怎么能够把依赖注入使用简单注射器这个属性?我google了一段时间,但我发现的唯一的事情是Ninject,或注入的WebAPI的过滤器。

So, my question is how can I inject dependencies into this attribute using Simple Injector? I google for a while but the only thing I found was for Ninject, or inject filters on WebAPI.

干杯!

推荐答案

您不能做的构造函数注入的属性,因为它是谁是在创作属性控制CLR;不是DI库。虽然他们已经创建后,你可以初始化/积聚的属性和使用属性注入注入依赖,这是由于以下原因非常危险的:

You can't do constructor injection into attributes, because it is the CLR who is in control over the creation of attributes; not the DI library. Although you could initialize/build-up attributes after they have been created and inject dependencies using property injection, this is very risky for the following reasons:

  • Many frameworks cache attributes, which make them effectively singletons. This will cause Captive Dependencies in cases the dependencies themselves aren't singletons themselves.
  • It will be hard to impossible to let the container verify object graphs that start from the attributes, which might cause a false sense of security when verifying and diagnosing the container's configuration.

相反,更好的方法是要么做要么属性被动不起眼的对象

Instead, a much better approach is to either make attributes either passive or humble objects.

通过一个不起眼的对象,则提取所有逻辑出的属性变成自己的服务。只有code将在属性被剩下的就是你的容器或服务定位器的调用,以解决服务和调用方法。这可能是这样的(原谅我的C#):

With a humble object, you extract all logic out of the attribute into its own service. The only code that will be left in the attribute is a call to your container or Service Locator to resolve that service and you call the method. This might look like this (excuse my C#):

public class AuthRequiredAttribute : Attribute, IOperationBehavior
{
    public object BeforeCall(string operationName, object[] inputs) {
        var checker = Global.Container.GetInstance<IAuthorizationChecker>();
        checker.Check();
    }
}

// Attribute's logic abstracted to a new service. This service can be
// registered, verified, diagnosed, and tested.
public class AuthorizationChecker : IAuthorizationChecker
{
    private readonly IDS authenticationService;
    public AuthorizationChecker(IDS authenticationService) {
        this.authenticationService = authenticationService;
    }

    public void Check() {
        if (this.authenticationService.Usuario == null) {
            if (HttpContext.Current == null) {
                throw new SecurityException();
            } else {
                throw new WebFaultException<string>();
            }
        }
    }
}

这需要你揭露容器,你的属性可以解决他们所需要的服务的一种方式。这一优势是,它是很容易实现的,挺干净的。缺点是,你必须解决的服务定位器反模式得到这个工作,你必须确保你的服务被注册,因为容器不会警告这一点,因此这将在运行时,而不是在一个集成测试调用内部应用程序启动<$ C $失败C> container.Verify()。

This requires you to expose the container in a way that your attributes can resolve the services they need. Advantage of this is that it is easy implemented, quite clean. Downside is that that you have to resolve to the Service Locator anti-pattern to get this working, and you have to make sure that your service is registered, because the container won't warn about this and this will therefore fail at runtime instead of during application startup of inside an integration test that calls container.Verify().

第二个选择是使用被动属性。当你有这些属性的倍数时特别有用。 本文介绍后面被动属性的基本概念,并给出一个例子如何在网页API实现这一点。 WCF有不同的拦截点,所以将这种向WCF需要一个不同的实施,但概念保持相同。

The second option is using passive attributes. This is especially useful when you have multiple of these attributes. This article describes the basic idea behind passive attributes and gives an example how to implement this in Web API. WCF has different interception points, so applying this to WCF requires a different implementation, but the concept stays the same.

这篇关于如何注入到dependencis与WCF简单的喷油器属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆