Reputation: 11
Building a C# Azure Function v2 project using Visual Studio 2017. I defined just one function, but during the HTTP triggered execution several classes are instantiated. Most by my own code, some by JSON deserialization (so no control over how to call the constructor).
The function methods signature receives an ILogger instance that I use for logging. What is the best way to let all my class instances make use of that same ILogger instance, without having to pass ILogger to every class instantiation?
I understand using a static var is not possible, since they are shared between different function invocations, while each invocation receives another ILogger instance.
Also, Dependency Injection seems not to be in place here, since the classes are used only internally, except for the JSON deserializable classes.
Following is my summarized code. I could pass ILogger the the MyClass constructor, but myClass.PerformTheTask() performs complex code that uses and intantiates several classes, that all need to log stuff.
What is best way forward here?
[FunctionName("FunctionName")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "someroute{route}")] HttpRequest req,
ILogger log,
ExecutionContext context)
{
var myClass = new myClass(); //how to make myClass and its children access ILogger?
myClass.PerformTheTask();
}
Upvotes: 1
Views: 2196
Reputation: 5294
@EricG,
As rightly said by Fredrik, You can use Dependency injection in Azure function V2 which is supported now.Azure Functions builds on top of the ASP.NET Core Dependency Injection features.
You can find the Azure samples here and in the git repo for reference.
It's quite easy to use and more cleaner.It uses constructor injection for injecting the dependency.
public class SampleFunction
{
private readonly MyServiceA _serviceA;
private readonly MyServiceB _serviceB;
private readonly IGlobalIdProvider _globalIdProvider;
public SampleFunction(MyServiceA serviceA, MyServiceB serviceB, IGlobalIdProvider globalIdProvider)
{
_serviceA = serviceA ?? throw new ArgumentNullException(nameof(serviceA));
_serviceB = serviceB ?? throw new ArgumentNullException(nameof(serviceB));
_globalIdProvider = globalIdProvider ?? throw new ArgumentNullException(nameof(globalIdProvider));
}
[FunctionName("SampleFunction")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation($"Service A ID: {_serviceA.IdProvider.Id}. Service B ID: {_serviceB.IdProvider.Id}");
return new OkObjectResult(new
{
ProvidersMatch = ReferenceEquals(_serviceA.IdProvider, _serviceB.IdProvider),
GlobalId = _globalIdProvider.Id,
ServiceAId = _serviceA.IdProvider.Id,
ServiceBId = _serviceB.IdProvider.Id
});
}
}
Similarly you can do it with ILogger and use it in classes. Hope it helps.
Upvotes: 1