Closed Plasma closed 3 years ago
UPDATE: Please see the Blazor integration guide for the latest information on integrating with Blazor.
To my knowledge, nothing has changed in the .NET Core 3.x space that would improve the situation. Improvements are planned in .NET Core 5.0.
Thanks for the update. Would this be fixable by having SI be delegated to from the native dependency resolver? I thought it was supposed to be queried by the native DI framework if it couldn’t resolve something, is there a hook point for that?
I know it already crosswires the other way but I want the inverse I think
Inverse cross wiring is not possible, because MS.DI doesn't allow unregistered type resolution. You can, of course, register individual delegates into MS.DI that cal back into Simple Injector, but you'll have to do that for every dependency you need to resolve from within your Razor page.
With ASP.NET Core 5.0, the creation of Razor components can be intercepted and forwarded to Simple Injector. Here is how to do it:
// Custom component activator
public class SimpleInjectorComponentActivator : IComponentActivator
{
private readonly Container container;
public SimpleInjectorComponentActivator(Container container) => this.container = container;
public IComponent CreateInstance(Type type) => (IComponent)this.container.GetInstance(type);
}
// Add the custom component activator to ASP.NET Core:
services.AddSingleton<IComponentActivator>(
new SimpleInjectorComponentActivator(container));
Also make sure to register all your components up-front, e.g.:
foreach (Type type in container.GetTypesToRegister<IComponent>(typeof(MyComponent).Assembly))
{
container.Register(type);
}
In case you wish your components to be initializable with properties (note: you should prefer using Constructor Injection), you can add a custom property injection behavior to inject properties marked with InjectAttribute
, as described here.
Thank you for this
I'm using a custom RazorPage<TModel>
which I'd like to have dependencies injected into. It needs a parameterless constructor for MVC, meaning I have to use property injection. From the context of this ticket I assumed the following would work, but it doesn't. Is this a different issue?
# MyRazorPage.cs
public abstract class MyRazorPage<TModel> : RazorPage<TModel>
{
[Import]
public ITenantContextProvider<TenantContext> tenantProvider { get; init; }
public TenantContext? Tenant => tenantProvider.GetContext();
}
#_ViewImports.cshtml
@inherits MyRazorPage<TModel>
I'm assuming IPropertySelectionBehavior
and IComponentActivator
would work here as well, but it doesn't. The property remains null
. Furthermore if I use RazorInject
I'm getting an exception from Microsoft DI that ITenantContextProvider<TenantContext>
is not a registered service:
System.InvalidOperationException: No service for type 'ITenantContextProvider`1[TenantContext]' has been registered.
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.AspNetCore.Mvc.Razor.RazorPagePropertyActivator.<>c__DisplayClass8_0.<CreateActivateInfo>b__1(ViewContext context)
at Microsoft.Extensions.Internal.PropertyActivator`1.Activate(Object instance, TContext context)
at Microsoft.AspNetCore.Mvc.Razor.RazorPagePropertyActivator.Activate(Object page, ViewContext context)
at Microsoft.AspNetCore.Mvc.Razor.RazorPageActivator.Activate(IRazorPage page, ViewContext context)
Hi @Bouke, if I'm not mistaken, this question is more about razor pages, rather than Razor components. That deserves a new thread, but I haven't got a quick answer for you. I will have to look into that, which might take some time.
Thank you for looking into this, I have created simpleinjector/SimpleInjector.Integration.AspNetCore#25 for this.
Hello,
I came across https://github.com/simpleinjector/SimpleInjector/issues/442#issuecomment-334430299 mentioning how
@inject IMyService myService
in Razor ASP.NET Core was not supported.This comment was a while ago, and so wanted to double-check to see if .NET Core 3.x had any improvements to allow SimpleInjector to work with
@inject
?Index.cshtml
This is a nicer way to inject a context object for the page, instead of wrapping in a ViewBag for example.
Thank you