使用SimpleInjector中的IAuthorizationFilter进行依赖项注入 [英] Dependency injection with IAuthorizationFilter in SimpleInjector

查看:135
本文介绍了使用SimpleInjector中的IAuthorizationFilter进行依赖项注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 PermissionFilter 类,该类实现了 System.Web.Mvc 中的 IAuthorizationFilter .由于它具有已经映射的依赖项,因此我想使用SimpleInjector来提供它.

I have a class PermissionFilter that implements IAuthorizationFilter from System.Web.Mvc. Since it has dependencies that are already mapped, I want to use SimpleInjector to provide it.

我正在这样做(与Ninject一起使用):

I'm doing this (which was working with Ninject):

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(DependencyResolver.Current.GetService(typeof(PermissionFilter)));
}

但是我得到了错误:

值不能为null.参数名称:实例

Value cannot be null. Parameter name: instance

我试图从容器中获取 PermissionFilter 的实例:

I tried to get an instance of the PermissionFilter from the container:

var permissionFilter = container.GetInstance(typeof(PermissionFilter));
filters.Add(permissionFilter);

但是使用SimpleInjector时,它会到达以下代码:

But with SimpleInjector, when it reaches this code:

container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

我收到一条 InvalidOperationException 并显示以下消息:

I get an InvalidOperationException with the message:

在第一次调用GetInstance,GetAllInstances和Verify之后不能更改容器.请参阅 https://simpleinjector.org/locked 了解容器为何被锁定.

推荐答案

在编写问题时,SO提示我检查此问题和史蒂芬.他在那说:

As I was writing the question, I was prompted by SO to check this question and the great answer by Steven. There he says:

MVC全局过滤器只是实例列表.这意味着此类过滤器所具有的任何依存关系也将变成单例.这意味着您应该对这种方法非常小心,因为偶然导致

MVC global filters are just a list of instances. This means that any dependencies such filter has, also become singletons. This means you should be very careful with this approach, because it is really easy to accidentally cause a Captive Dependency in your application. Captive Dependencies are often hard to track and often only popup in testing or production.

相反,您应该创建一个代理类,该代理类可以在使用过滤器时委派回您的容器/内核,以便可以当场解析实际的过滤器.这样可以防止强制依赖性.

Instead, you should create a proxy class that can delegate back to your container/kernel at the time the filter is used, so it can resolve the real filter on the spot. This prevents Captive Dependencies.

所以,我最终编写了这个代理类:

So, I ended up writing this proxy class:

public class AuthorizationFilterProxy<TFilter> : IAuthorizationFilter
    where TFilter : class, IAuthorizationFilter
{
    private readonly Container Container;

    public AuthorizationFilterProxy(Container container)
    {
        Container = container;
    }

    public void OnAuthorization(AuthorizationContext context)
    {
        Container.GetInstance<TFilter>().OnAuthorization(context);
    }
}

添加过滤器:

public static void RegisterGlobalFilters(
    GlobalFilterCollection filters, Container container)
{
    // Since PermissionFilter is a root type (i.e. directly resolved from the container),
    // it should be explicitly registered. This allows it to be verified.
    container.Register<PermissionFilter>();

    filters.Add(new AuthorizationFilterProxy<PermissionFilter>(container));
}

这篇关于使用SimpleInjector中的IAuthorizationFilter进行依赖项注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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