简体   繁体   中英

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. 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? How do I work with CallerMemberName in that case? Is it possible, anyway?

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.

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).

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. 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.

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 .

am I doing something wrong?

You are. For the reasons I described above.

How do I work with CallerMemberName in that case?

You can't. CallerMemberNameAttribute is not intended for this purpose. It's intended for quick-and-easy logging, profiling, and tracing.

Is it possible, anyway?

Yes - by extending Microsoft.Extensions.DependencyInjection correctly. Please read the MEDI documentation for more details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM