ASP.NET Core 5 如何在 _ViewImports.cshtml 中注入动态类型对象

ASP.NET Core 5 How to Inject Dynamic Typed Object in _ViewImports.cshtml

当我尝试在 _ViewImports.cshtml

中执行此操作时
@inject dynamic ResourceManager;

我可以像下面这样在我的视图中使用它:

Some text @ResourceManager.MyRuntimeBoundProperty some more text

但是,当我尝试 运行 这个解决方案时,我得到了这个异常:

System.InvalidOperationException: No service for type 'System.Object' has been registered. Source: Microsoft.Extensions.DependencyInjection.Abstractions

堆栈跟踪:

at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) in /_/src/libraries/Microsoft.Extensions.DependencyInjection.Abstractions/src/ServiceProviderServiceExtensions.cs:line 59

我想避免为 ResourceManager 指定实际类型,因为它的属性是在 运行 时间设置的,并且可能会有很大差异。

有没有办法在 _ViewImports.cshtml 中指定一个动态对象,或者以其他方式在我的所有视图中访问一个动态填充的 ResourceManager?

您不能将动态与依赖项注入一起使用,因为 DI 通过使用 types 作为主要机制来确定应将哪些实例注入到您的依赖组件中。所以如果你想在这里使用依赖注入,你将需要使用一些静态类型。

解决这个问题的一种方法是引入一个静态类型的包装器对象,然后它提供对动态对象的访问。例如。像这样:

public class ResourceManagerWrapper
{
    public dynamic Resources { get; set; }
}

如果您将其注册为作用域或单例依赖项,则可以在您的管道中更早地注入它,将 Resources 对象设置为您的动态资源管理器,然后在您的视图中访问它:

@inject ResourceManagerWrapper resourceManager

Some text @resourceManager.Resources.MyRuntimeBoundProperty some more text

另一种解决方案是不在此处使用依赖项注入,而是将此动态资源管理器直接传递到您的视图中。您可以通过视图模型或使用 Razor 视图可用的 ViewData 机制来执行此操作。这样,您可以设置一些 ViewData["ResourceManager"] 然后在您的视图中加载该值:

@{
    dynamic resourceManager = ViewData["ResourceManager"];
}

您也可以在 _ViewStart.chtml 中执行此操作,以便它在您的所有视图中默认运行。