{ initialize.QueryProc-6ren">
gpt4 book ai didi

asp.net-mvc - 简单注入(inject)器 2.6 中的 "An MVC filter provider has already been registered for a different Container instance."

转载 作者:行者123 更新时间:2023-12-02 20:39:01 25 4
gpt4 key购买 nike

我之前在我的属性之一中设置了属性注入(inject)

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

用法是

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

但是更新到 simpleinjector 2.6.1 后,属性注入(inject)中断了。当我尝试访问 PermitAttribute 内的 QueryProcessor 对象时。它解析 null 值,因为简单注入(inject)器配置仍然通过委托(delegate)实例具有相同的属性注入(inject)。

属性注入(inject)行为是否有任何重大变化,导致它在 v2.5 中工作而在 2.6.1 中不再工作?

更新1:

配置中的行在 v2.6.1 中为属性注册 MVC 过滤器提供程序时抛出错误

 container.RegisterMvcIntegratedFilterProvider();

为此我评论了它。并且它停止了属性(property)注入(inject)的工作。属性注入(inject)位于我的属性之一内。我想这就是上面影响它的那一行。以及 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 Work\RemsPortal\V2.0 Web Portal\RemsPortal\App_Start\SimpleInjectorInitializer.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, Guid>, RemsRoleManager>();

Container.Register<IUserStore<Users, Guid>,
UserStore<Users, Roles, Guid, UserLogins, UserRoles, Claims>>();
Container.Register<IRoleStore<Roles, Guid>, RoleStore<Roles, Guid, 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 中添加的验证检查引起的,该验证检查阻止您针对不同的情况多次调用 RegisterMvcAttributeFilterProviderRegisterMvcIntegratedFilterProvider容器实例。该问题有更详细的描述here .

解决方案是确保在整个应用程序域期间以及自 RegisterMvcAttributeFilterProvider is deprecated 起,在代码中仅调用 RegisterMvcIntegratedFilterProvider 一次。 ,完全防止对该遗留方法进行任何调用。因此,如果您只有一次调用,请在这一行设置一个断点,因为您可能会调用 Initialize() 方法两次!

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

另一个选项是启用 explicit property injection对于属性,或者依靠 passive attributes 的使用如图here .

但是关于属性注入(inject)的一个注释。我注意到您广泛使用(显式)属性注入(inject),特别是对于您的基类。然而,从设计的角度来看,最好将基类全部删除,因为它们至少是一种设计味道,但以后可能会成为维护问题。它们可能违反单一职责原则,或者至少隐藏派生类型具有太多依赖项,这通常意味着太多职责。我自己使用 MVC 和 command handlers 创建了相当大的应用程序和 query handlers我总是能够阻止使用基类。如果具体处理程序需要依赖项,您只需将其注入(inject)到该类型的构造函数中即可。通过(ab)使用基本类型来防止隐藏该依赖关系。

使用 RegisterMvcIntegratedFilterProvider 时,您应该注意一个重要细节。 MVC 缓存过滤器属性(天知道为什么),这意味着此类属性基本上变成了单例。这意味着该过滤器属性所具有的每个依赖项也将成为单例。如果这种依赖本身没有注册为单例,这当然是个大问题;它变成 captive dependency 。尽管简单注入(inject)器包含 a diagnostic warning要检测此类错误,简单注入(inject)器将无法使用属性检测到这种错误,因为属性未在容器中注册。因此,我的建议是完全不要在属性中使用属性注入(inject)。 我们正在考虑弃用 MVC 集成库中的 RegisterMvcIntegratedFilterProvider 方法。

关于asp.net-mvc - 简单注入(inject)器 2.6 中的 "An MVC filter provider has already been registered for a different Container instance.",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27033711/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com