首页 > 解决方案 > ASP.NET Core 5 如何在 _ViewImports.cshtml 中注入动态类型对象

问题描述

当我尝试在我的 _ViewImports.cshtml 中执行此操作时

@inject dynamic ResourceManager;

我可以在我的视图中使用它,如下所示:

Some text @ResourceManager.MyRuntimeBoundProperty some more text

但是,当我尝试运行此解决方案时,出现此异常:

System.InvalidOperationException:没有为“System.Object”类型注册服务。来源: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?

标签: asp.net-coredependency-injection

解决方案


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

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

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

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

@inject ResourceManagerWrapper resourceManager

Some text @resourceManager.Resources.MyRuntimeBoundProperty some more text

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

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

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


推荐阅读