加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – “一个MVC过滤器提供程序已经注册了另一个Contai

发布时间:2020-12-16 03:59:44 所属栏目:asp.Net 来源:网络整理
导读:我以前在我的一个属性中设置了属性注入设置 Container.RegisterInitializerPermitAttribute(initialize = { initialize.QueryProcessor = Container.GetInstanceIQueryProcessor(); }); 用法是 public class PermitAttribute : ActionFilterAttribute{ publi
我以前在我的一个属性中设置了属性注入设置

Container.RegisterInitializer<PermitAttribute>(initialize =>
 {
     initialize.QueryProcessor = Container.GetInstance<IQueryProcessor>();
 });

用法是

public class PermitAttribute : ActionFilterAttribute
{       
    public IQueryProcessor QueryProcessor { get; set; }
}

但在更新到simpleinjector之后2.6.1属性注入破了.当我试图访问PermitAttribute内的QueryProcessor对象时.它解析了null值,因为Simple Injector配置仍然通过委托实例注入相同的属性.

由于它在v2.5中工作并且在2.6.1中不再起作用,属性注入行为是否有任何重大变化?

更新1:

配置中的Line为MVC过滤器提供程序注册v2.6.1中的属性引发了错误

container.RegisterMvcIntegratedFilterProvider();

为此我评论了它.它阻止了房产注入工作.属性注入是我的一个属性.我想这就是影响它的线.它在v2.6.1中抛出错误

更新2:

信息

An MVC filter provider has already been registered for a different
Container instance. Registering MVC filter providers for different
containers is not supported by this method.

堆栈跟踪 :

at SimpleInjector.SimpleInjectorMvcExtensions.RequiresFilterProviderNotRegistered(Container container)
at SimpleInjector.SimpleInjectorMvcExtensions.RegisterMvcIntegratedFilterProvider(Container container)
at RemsPortal.App_Start.SimpleInjectorInitializer.Initialize() in d:Projects WorkRemsPortalV2.0 Web PortalRemsPortalApp_StartSimpleInjectorInitializer.cs:line 39

更新3:

整个配置

public static void Initialize()
{
    var container = new Container();

    InitializeContainer(container);
    container.RegisterMvcIntegratedFilterProvider();
    container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

    container.Verify();

    DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
}

private static void InitializeContainer(Container Container)
{
    Container.RegisterManyForOpenGeneric(typeof(IAsyncCommandHandler<,>),AppDomain.CurrentDomain.GetAssemblies());
    Container.RegisterOpenGeneric(typeof(ITransactionCommandHandler<,typeof(TransactionCommandHandlerDecorator<,>));
    Container.RegisterOpenGeneric(typeof(ICommandResult<>),typeof(CommandHandlerResult<>));
    Container.Register<ICommandResolver,CommandResolver>();

    Container.Register<DbContext,RemsContext>();

    Container.RegisterOpenGeneric(typeof(IPager<>),typeof(PagerModel<>));

    //Container.RegisterPerWebRequest<DbContext,RemsContext>();

    Container.Register<UserManager<Users,Guid>,RemsUserManager>();
    Container.Register<RoleManager<Roles,RemsRoleManager>();

    Container.Register<IUserStore<Users,UserStore<Users,Roles,Guid,UserLogins,UserRoles,Claims>>();
    Container.Register<IRoleStore<Roles,RoleStore<Roles,UserRoles>>();

    Container.RegisterManyForOpenGeneric(typeof(IAsyncQueryHandler<,AppDomain.CurrentDomain.GetAssemblies());
    Container.RegisterManyForOpenGeneric(typeof(IAsyncQueryHandler<>),AppDomain.CurrentDomain.GetAssemblies());
    Container.RegisterManyForOpenGeneric(typeof(IQueryHandler<,AppDomain.CurrentDomain.GetAssemblies());
    Container.RegisterOpenGeneric(typeof(IQueryResult<>),typeof(QueryResult<>));

    Container.RegisterOpenGeneric(typeof(IPaginator<>),typeof(Paginator<>));
    Container.Register<IPaginator,Paginator>();

    Container.RegisterOpenGeneric(typeof(IAsyncQueryHandler<>),typeof(BaseQuery<>));
    Container.RegisterOpenGeneric(typeof(IQueryHandler<>),typeof(BaseQuery<>));

    Container.Register<IQueryProcessor,QueryProcessor>(Lifestyle.Singleton);

    Container.Register<ILog,NLogger>(Lifestyle.Singleton);

    Container.RegisterInitializer<PermitAttribute>(initialize =>
    {
        initialize.QueryProcessor = Container.GetInstance<IQueryProcessor>();
    });

    Container.RegisterInitializer<BaseController>(initialize =>
    {
        initialize.QueryProcessor = Container.GetInstance<IQueryProcessor>();
        initialize.Logger = Container.GetInstance<ILog>();
    });

    Container.RegisterInitializer<BaseCommandHandler>(initialize =>
    {
        initialize.UserManager = Container.GetInstance<RemsUserManager>();
        initialize.RoleManager = Container.GetInstance<RemsRoleManager>();
        initialize.RemsContext = Container.GetInstance<RemsContext>();
        initialize.QueryProcessor = Container.GetInstance<IQueryProcessor>();
    });

    Container.RegisterInitializer<BaseHandler>(initialize =>
    {
        initialize.UserManager = Container.GetInstance<RemsUserManager>();
        initialize.RolesManager = Container.GetInstance<RemsRoleManager>();
    });
}

解决方法

您看到的异常是由已添加到2.6版的验证检查引起的,该验证检查阻止您多次为不同的容器实例调用RegisterMvcAttributeFilterProvider和RegisterMvcIntegratedFilterProvider.更详细地描述了该问题 here.

解决方案是确保RegisterMvcIntegratedFilterProvider在整个应用程序域的持续时间内仅在代码中调用一次,从RegisterMvcAttributeFilterProvider is deprecated开始,防止对该传统方法进行任何调用.因此,如果你只有一个调用,在这一行设置一个断点,因为你可能会调用两次Initialize()方法!

新的RegisterMvcIntegratedFilterProvider允许在Simple Injector pipeline中完全集成MVC属性,这确保在属性上调用RegisterInitializer方法.

另一种选择是为explicit property injection启用属性,或者使用passive attributes,如here所示.

但关于房地产注资的一点说明.我注意到你大量使用(显式)属性注入,特别是对你的基类.但是从设计的角度来看,最好一起删除基类,因为它们至少是一种设计气味,但可能会在以后成为维护问题.它们可能违反单一责任原则或至少隐藏派生类型具有太多依赖性,这通常意味着太多的责任.我自己用MVC和command handlers和query handlers创建了很大的应用程序,我总是能够阻止使用基类.如果具体的处理程序需要依赖项,则只需将其注入该类型的构造函数中即可.防止使用基类型(ab)隐藏该依赖项.

使用RegisterMvcIntegratedFilterProvider时,您应该注意一个重要的细节. MVC缓存过滤器属性(上帝知道为什么),这意味着这样的属性基本上变成了单身.这意味着此过滤器属性所具有的每个依赖项也会成为单例.如果这种依赖没有被注册为单身本身,这当然是个大问题;虽然Simple Injector包含a diagnostic warning来检测这些类型的错误,但Simple Injector将无法使用属性检测到这一点,因为属性未在容器中注册.因此,我的建议是远离在属性中使用属性注入.我们正在考虑从MVC集成库中弃用RegisterMvcIntegratedFilterProvider方法.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读