Open oleg-gochachko opened 5 years ago
Thank you for reporting this issue. This part of the ASP.NET Core stack is still something that might need improvement.
Your issue is a bit tricky, because there are a few things going on. First of all, the resolved type is a generic type defined internally inside the Microsoft libraries. That's why it hasn't been registered by Simple Injector. It only registers concrete, non-generic types that are part of application parts of type IApplicationPartTypeProvider
.
The SimpleInjectorPageModelActivatorProvider
requires types to be registered explicitly, which is similar to what the built-in MS.DI container requires. In the case of Page Models, however, Microsoft seems to circumvent that default behavior and circumvents going through the built-in container. Instead, the built-in IPageModelActivatorProvider
has its own DI mechanism and only resolves Page Model's dependencies from the built-in container.
This is why the built-in behavior can resolve an Microsoft.AspNetCore.Identity.UI.V4.Pages.Account.Internal.LogoutModel<Microsoft.AspNetCore.Identity.IdentityUser>
. The Simple Injector implementation, however, checks to see whether the type is registered. If this is not the case, it will fall back to using the built-in MS.DI container. That, unfortunately, won't work either, because that type isn't registered in MS.DI at all: it is the built-in IPageModelActivatorProvider
that takes over.
We will have to figure out how to work with this scenario, without having to revert to weird hacks that prevent DI-container verification. A huge problem here is that the class in question is internal. This makes it very hard to register it by hand.
For now, you can work around the issue by doing the following:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSimpleInjector(container, options =>
{
options.AddAspNetCore()
.AddControllerActivation()
.AddViewComponentActivation()
.AddPageModelActivation()
.AddTagHelperActivation();
});
services.AddSingleton<IPageModelActivatorProvider>(
new FixedPageModelActivatorProvider(
container,
new SimpleInjectorPageModelActivatorProvider(container)));
}
Here, FixedPageModelActivatorProvider
is a custom class that is defined as follows:
public class FixedPageModelActivatorProvider : IPageModelActivatorProvider
{
private readonly Container container;
private readonly IPageModelActivatorProvider decoratee;
public FixedPageModelActivatorProvider(Container container, IPageModelActivatorProvider decoratee)
{
this.container = container;
this.decoratee = decoratee;
}
public Func<PageContext, object> CreateActivator(CompiledPageActionDescriptor descriptor)
{
try
{
return this.decoratee.CreateActivator(descriptor);
}
catch (InvalidOperationException)
{
var producer = Lifestyle.Transient.CreateProducer(
serviceType: descriptor.ModelTypeInfo.AsType(),
implementationType: descriptor.ModelTypeInfo.AsType(),
container: this.container);
return _ => producer.GetInstance();
}
}
public Action<PageContext, object> CreateReleaser(CompiledPageActionDescriptor descriptor) =>
this.decoratee.CreateReleaser(descriptor);
}
This should fix your problem for now, until we have a good fix for this problem.
feature-728 branch created.
Hi @oleg-gochachko,
I'm currently trying to implement a fix for this issue. I, however, need to test my assumptions, but have little experience with PageModels myself. Would you be so kind to provide me with a small sample ASP.NET Core application that reproduces the issue?
I postponed this feature until I have more information available. Feel free to provide me with information that helps me address this issue.
I follow https://simpleinjector.org/aspnetcore guide to integrate SI to my web site (standard template with authentication).
However, when I try to open login page - I recieve the folloving error:
Stack trace:
After several hours of tries I'm able to start the project propery by using these configurations:
and
As you may see method
.AddPageModelActivation()
commented and obsolete methodRegisterPageModels(app);
andservices.AddSingleton<IPageModelActivatorProvider>
added.I think
AddPageModelActivation
not enumerate some of Identity view models and should be fixed.