我有一个类PermissionFilter,它从System.Web.Mvc实现IAuthorizationFilter。由于它有已经映射的依赖项,所以我希望使用SimpleInjector来提供它。
我正在做这件事(这是和尼尼特一起工作的):
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(DependencyResolver.Current.GetService(typeof(PermissionFilter)));
}但我知道错误是:
值不能为空。参数名称:实例
我试图从容器中获取PermissionFilter的一个实例:
var permissionFilter = container.GetInstance(typeof(PermissionFilter));
filters.Add(permissionFilter);但是对于SimpleInjector,当它到达以下代码时:
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());我得到了一个InvalidOperationException,上面有这样的信息:
在第一次调用GetInstance、GetAllInstances并进行验证之后,无法更改容器。请参阅https://simpleinjector.org/locked以了解为什么容器是锁定的。
发布于 2018-03-01 15:02:23
当我写这个问题的时候,我被SO提示去检查这个问题,伟大的答案是由史蒂文来检查的。他在那里说:
MVC全局过滤器只是一个实例列表。这意味着这样的过滤器所具有的任何依赖项,也会变成单例。这意味着您在使用这种方法时应该非常小心,因为在您的应用程序中很容易意外地导致圈养依附。捕获依赖经常很难跟踪,而且通常只在测试或生产中弹出。 相反,您应该创建一个代理类,它可以在使用过滤器时委托给容器/内核,这样它就可以当场解析真正的过滤器。这就防止了圈养属地。
因此,我最终编写了这个代理类:
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));
}https://stackoverflow.com/questions/49052523
复制相似问题