How inject dependency in custom TelemetryInitializer?
Asked Answered
M

2

6

We are using Autofac 4 for DI and I started experimenting with AI a short while ago. Now I created a IdentityTelemetryInitializer class which needs and IIdentityProvider to be able to get the ID of the current authorized user and set it add it to the context. I cannot find a way in which to inject dependencies into a TelemetryInitializer. If I define a contructor that takes an IIdentityProvider, the custom initializer is skipped altogether. Any ideas are welcome. I was thinking of having the user ID also set as the Thread Principal so that we can access it this way, but I was hoping I could use DI for this?

Marcela answered 10/6, 2016 at 14:38 Comment(1)
What do youm ean by "the custom initializer is skipped altogether" ? do you mean that the base ctor is not called ?Cordelia
E
0

You cannot inject dependencies using a constructor as the initializer initialized internally using the default (empty) constructor. When you explicitly defined a new ctor you've actually 'removed' the default one, thus the initializer was skipped altogether, as you've mentioned.

Therefore, the only way is to resolve the dependencies during the 'Initialize' method, after registering them on application startup.

ctx.RegisterType<MyService>().As<IService>().AsSelf(); // on application startup
ctx.Resolve<IService>(); // during initializer 'Initialize' method
Erasmo answered 11/6, 2016 at 9:8 Comment(4)
Thanks for the answer. I tried it out, however, the dependency is registered in Autofac via .InstancePerRequest(). The telemetry initializer class seems to live in a different (longer lifetime) scope and has no access to per-request dependencies :-(Marcela
@ParaJaco can't you use the HttpContext to resolve the dependency? from Autofac documentation - How do I work with per-request lifetime scope?: "If you have application startup code or a background thread in an ASP.NET MVC app trying to use DependencyResolver.Current - the AutofacDependencyResolver requires a web context to resolve things. When you try to resolve something from the resolver, it’s going to try to spin up a per-request lifetime scope and store it along with the current HttpContext"Erasmo
I would not know how to do that, would you have an example of how this could be done?Marcela
@Erasmo (and others) : even if this works, it breaks somehow the promise of DI , or am I wrong somewhere ? What is wrong here ? is this the TelemetryInitializer API that is not good enough ? I guess this use case if very common and right now I don't see a practical solution to solve itMetronome
M
0

You might look at the question I asked here How to have "Request" events with authenticated user id ?

because I had managed to have the TelemetryInitializer working, passing user id via the HttpContext as suggested by @yonisha.

Off course it's not as lean as what you try to achieve.

The Telemetry Initializer is called each time you instanciate a Telemetry class, so really depending of how you manage them. Btw I am looking for good advice/best pratice on that : for the moment I have one private instance on each Controller that need to track something, but that does not smell good due to lifetime of Controller.

Metronome answered 28/3, 2018 at 13:16 Comment(1)
Indeed with some step back, my answer is not an answer to the question, but a workaround to solve the problem.Metronome

© 2022 - 2024 — McMap. All rights reserved.