作者:傻a2602909381 | 来源:互联网 | 2023-07-06 18:10
c#
如果我将这些属性应用于某些服务,然后将其注入到 DI 中,我正在尝试弄清楚将使用哪个CallerMemberName
或CallerFilePath
值。例如:
public class MyService: IMyService
{
public MyService([CallerMemberName] string name = null)
{
var name = name; // name is always null here
}
}
...
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped();
}
}
所以,我想,这是name
变量的预期值还是我做错了什么?CallerMemberName
在这种情况下我该如何工作?有可能吗?
回答
如果我将这些属性应用于某些服务,然后将其注入到 DI 中,我正在尝试弄清楚将使用哪个CallerMemberName
或CallerFilePath
值。
你不能。您的方法将不起作用,因为 ASP.NET Core ( Microsoft.Extensions.DependencyInjection
) 使用的默认 DI 系统使用动态注册,这意味着 AOT(C#-to-IL)和 JIT(IL-to-x64)编译器都不了解消费者DI 服务(请注意,尽管注册在概念上是静态的并且只能在启动时执行 - 这只是一种错觉:您可以在运行时轻松破解默认的 DI 容器)。
作为侧边栏:您的方法唯一可行的时间是,如果您有某种代码生成系统在构建时创建对象工厂和服务工厂,而不使用任何运行时反射或 IL 生成。在实践中,您看到该方法在单元测试代码中使用的唯一地方,其中测试需要严格控制每个依赖项 - 但它们通常是手工编写的,而且非常乏味和脆弱。通过 Roslyn 代码生成,我希望看到静态服务工厂开始被更多地使用,因为它为您提供编译时保证每个依赖项都可用 - 这样您在运行时就不会因为缺少依赖项而感到任何令人讨厌的意外。
将[CallerMemberName]
和[CallerFilePath]
属性由AOT编译器,不是JIT编译器填充,即使它是由JIT编译器也不会帮助,因为一个DI服务的消费者不是服务的构造函数的调用者。
难道我做错了什么?
你是。由于我上面描述的原因。
CallerMemberName
在这种情况下我该如何工作?
你不能。CallerMemberNameAttribute
不用于此目的。它旨在快速轻松地进行日志记录、分析和跟踪。
有可能吗?
是的 - 通过Microsoft.Extensions.DependencyInjection
正确扩展。请阅读 MEDI 文档了解更多详情。