Reputation: 434
In my ASP.NET Core 2 project, I create new class that inherits the RazorPage class to add some additional property in views.
public abstract class WebViewPage<TModel> : Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>
{
public string Version
{
get
{
return "1.00.100";
}
}
public User CurrentUser
{
get
{
//challenge is here:
//return _services.GetRequiredService<IUserService>().GetCurrentUser();
}
}
}
public abstract class WebViewPage : WebViewPage<dynamic>
{
}
and _ViewImport.cshtml
file changed to this:
@inherits MyProject.WebViewPage<TModel>
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
The project works fine till challenge codes are marked as comment. but, how can I inject dependencies to the abstract class? or how to Resolve services in abstract class?
This is my StartUp.cs
file:
public void ConfigureServices(IServiceCollection services)
{
services.AddMemoryCache();
services.AddMvc();
services.AddTransient<IUserService, UserService>();
//services.AddScoped<IRazorPage<?>, WebViewPage<?>(); // ?: challenge!
}
Upvotes: 6
Views: 8642
Reputation: 387557
If you need access to the service provider inside of your razor page, you could access the HttpContext
through the Context
property, e.g.:
var userService = Context.RequestServices.GetRequiredService<IUserService>();
A possibly better alternative would be to have a constructor that takes the IUserService
as a dependency. So implementations of your type would have to pass that dependency on, essentially requiring them to have a constructor dependency on their own (which makes a good explicit design).
As for that dependency registration part, note that you generally cannot register abstract classes because they cannot be instantiated.
But in general, in order to register a generic type, you have to use the more verbose overload of AddScoped
which takes actual Type
arguments:
services.AddScoped(typeof(IRazorPage<>), typeof(WebViewPage<>));
Making a generic method call requires a real type as a generic type argument, so you would have to specify a concrete type for the type argument T
inside IRazorPage<T>
and WebViewPage<T>
. Since you explicitly do not want to use a concrete type there but instead want to tell the dependency injection container to support any type, you cannot use this syntax there.
Since the typeof
operator can determine the actual generic type, you can use it without having to use a specific type argument which would limit the registration to a single type.
Upvotes: 8