[英]Get caller info for injected service in .net core
I'm trying to figure out which CallerMemberName
or CallerFilePath
value will be used if I'll apply these attributes to some service and then inject it into DI.如果我将这些属性应用于某些服务然后将其注入 DI,我正在尝试找出将使用哪个
CallerMemberName
或CallerFilePath
值。 For example:例如:
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<IMyService, MyService>();
}
}
So, I guess, is it expected value for the name
variable or am I doing something wrong?所以,我想,是
name
变量的预期值还是我做错了什么? How do I work with CallerMemberName
in that case?在这种情况下,我该如何使用
CallerMemberName
? Is it possible, anyway?有可能吗?
I'm trying to figure out which
CallerMemberName
orCallerFilePath
value will be used if I'll apply these attributes to some service and then inject it into DI.如果我将这些属性应用于某些服务然后将其注入 DI,我正在尝试找出将使用哪个
CallerMemberName
或CallerFilePath
值。
You can't.你不能。 Your approach won't work because the default DI system used by ASP.NET Core (
Microsoft.Extensions.DependencyInjection
) uses dynamic registration which means neither the AOT (C#-to-IL) nor JIT (IL-to-x64) compiler knows anything about the consumers of a DI service (note that though the registration is conceptually static and can only be performed at startup - it's all just an illusion: you can easily hack the default DI container at runtime).您的方法行不通,因为 ASP.NET Core (
Microsoft.Extensions.DependencyInjection
) 使用的默认 DI 系统使用动态注册,这意味着 AOT (C#-to-IL) 和 JIT (IL-to-x64) 编译器都不知道任何关于DI 服务的消费者(请注意,虽然注册在概念上是static并且只能在启动时执行 - 这只是一种错觉:您可以在运行时轻松破解默认 DI 容器)。
As a sidebar: The only time where your approach would work was if you had some kind of code-generation system to create your object-factories and service-factories at build-time without using any runtime reflection or IL generation.作为补充:您的方法唯一可行的情况是,如果您有某种代码生成系统来在构建时创建您的对象工厂和服务工厂,而不使用任何运行时反射或 IL 生成。 In practice the only places you see that approach used it in unit-testing code where the tests need to strictly control every dependency - but they're often written by hand and it's very tedious and brittle.
在实践中,您看到该方法的唯一地方是在单元测试代码中使用它,在这些代码中测试需要严格控制每个依赖项——但它们通常是手工编写的,而且非常乏味和脆弱。 With Roslyn Code Generation I hope to see static service factories start to be used more because it gives you compile-time guarantees that every dependency is available - that way you don't get any nasty surprises at runtime about missing dependencies.
通过 Roslyn 代码生成,我希望看到static服务工厂开始被更多地使用,因为它为您提供了编译时保证每个依赖项都可用 - 这样您就不会在运行时遇到任何关于缺少依赖项的令人讨厌的意外。
The [CallerMemberName]
and [CallerFilePath]
attributes are populated by the AOT compiler, not the JIT compiler, and even if it was by the JIT compiler it won't help because a DI service's consumer is not the caller of a service's constructor . [CallerMemberName]
和[CallerFilePath]
属性由 AOT 编译器而非 JIT 编译器填充,即使是由 JIT 编译器填充也无济于事,因为DI 服务的使用者不是服务构造函数的调用者。
am I doing something wrong?
难道我做错了什么?
You are.你是。 For the reasons I described above.
由于我上面描述的原因。
How do I work with
CallerMemberName
in that case?在这种情况下,我该如何使用
CallerMemberName
?
You can't.你不能。
CallerMemberNameAttribute
is not intended for this purpose. CallerMemberNameAttribute
不适用于此目的。 It's intended for quick-and-easy logging, profiling, and tracing.它旨在用于快速简便的日志记录、分析和跟踪。
Is it possible, anyway?
有可能吗?
Yes - by extending Microsoft.Extensions.DependencyInjection
correctly.是 - 通过正确扩展
Microsoft.Extensions.DependencyInjection
。 Please read the MEDI documentation for more details.请阅读 MEDI 文档以获取更多详细信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.