【问题标题】:ASP.NET Core 5 How to Inject Dynamic Typed Object in _ViewImports.cshtmlASP.NET Core 5 如何在 _ViewImports.cshtml 中注入动态类型对象
【发布时间】:2021-08-09 01:12:17
【问题描述】:

当我尝试在我的 _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 Framework 4.7.2) 有一个提供动态 ResourceManager 的视图基类。我需要通过在 ASP.NET Core 5 迁移中使用动态 ResourceManager 来遵循这一点。我通过为 ResourceManager 提供一个具体类型,然后在使用它时将其转换为动态,然后从动态转换中访问各种属性名称来妥协。我不知道这是否真的有效,因为我没有运行那段代码。我怀疑它会,但现在还不能确认。谢谢你的建议。这也证实了我的想法。
  • 经典的 ASP.NET 虽然没有使用依赖注入。如果您想传递一个动态对象,我建议您将其传递为ViewData。你可以在你的控制器中设置它,或者甚至在你的_ViewStart.cshtml 中准备它,这样它就可以在任何地方使用。除此之外,您还可以注入一个类型正确的对象,该对象本身具有动态属性,然后您可以使用它来访问此资源管理器。
  • 谢谢你的这些想法,戳。我将与团队讨论!
  • 只是跟进:我使用了 Poke 创建具有动态属性的正确类型对象的想法,这就是我用来访问资源的方法。效果很好!戳,如果您想将其发布为您的答案,我会将其标记为答案,您可以获得您的信用:-)

标签: asp.net-core dependency-injection


【解决方案1】:

您不能将动态与依赖注入一起使用,因为 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 中执行此操作,以便它在您的所有视图中默认运行。

【讨论】:

  • 一个美丽而有用的答案!非常感谢!
猜你喜欢
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-04
  • 2018-09-13
  • 1970-01-01
  • 2018-08-23
  • 2022-01-25
相关资源
最近更新 更多