Reputation: 3129
I want to use Simple Injector to inject command handlers, ILogger and TelemetryClient in Azure Fuctions.
Here is my Azure Function:
[FunctionName("ReceiveEvent")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
ILogger log,
ICommandMapper commandMapper,
ICommandValidator commandValidator,
ICommandHandlerService commandHandlerService)
{
log.LogInformation("ReceiveEvent HTTP trigger function started processing request.");
IActionResult actionResult = null;
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var command = await commandMapper.Map(requestBody);
if (commandValidator.Validate(req, command, ref actionResult))
{
//TODO
commandHandlerService.HandleCommand(command);
return actionResult;
}
return actionResult;
}
Here is my Bootstrapper class:
public class Bootstrapper
{
public static void Bootstrap(IEnumerable<Assembly> assemblies = null, bool verifyContainer = true)
{
Container container = new Container();
container.Register(typeof(ICosmosDBRepository<>), typeof(CosmosDBRepository<>).Assembly);
container.Register(typeof(IAzureBlobStorage), typeof(AzureBlobStorage).Assembly);
container.Register(typeof(ICommandMapper), typeof(CommandMapper).Assembly);
container.Register(typeof(ICommandValidator), typeof(CommandValidator).Assembly);
container.Register(typeof(ICommandHandlerService), typeof(CommandHandlerService).Assembly);
List<Assembly> myContextAssemlies = new List<Assembly>
{
Assembly.GetAssembly(typeof(CardBlockCommandHandler)),
};
container.Register(typeof(ICommandHandler), myContextAssemlies, Lifestyle.Scoped);
assemblies = assemblies == null
? myContextAssemlies
: assemblies.Union(myContextAssemlies);
if (verifyContainer)
{
container.Verify();
}
}
}
Now my question is, how I'll resolve the DI with this bootstrapper method in Azure Function?
Do I need to register bootstrap method in FunctionsStartup?
Upvotes: 1
Views: 644
Reputation: 172646
With Simple Injector, you don't inject services into the Azure Function. This is not supported. Instead, the integration guide explains that:
Instead of injecting services into a Azure Function, move all the business logic out of the Azure Function, into an application component. The function's dependencies can become arguments of the component's constructor. This component can be resolved and called from within the Azure function.
For your particular case, this means executing the following steps:
public sealed class ReceiveEventFunction
{
private readonly ILogger log;
private readonly ICommandMapper commandMapper;
private readonly ICommandValidator commandValidator;
private readonly ICommandHandlerService commandHandlerService;
public ReceiveEventFunction(ILogger log, ICommandMapper commandMapper,
ICommandValidator commandValidator, ICommandHandlerService commandHandlerService)
{
this.log = log;
this.commandMapper = commandMapper;
this.commandValidator = commandValidator;
this.commandHandlerService = commandHandlerService;
}
public async Task<IActionResult> Run(HttpRequest req)
{
IActionResult actionResult = null;
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var command = await commandMapper.Map(requestBody);
if (commandValidator.Validate(req, command, ref actionResult))
{
commandHandlerService.HandleCommand(command);
return actionResult;
}
return actionResult;
}
}
[FunctionName("ReceiveEvent")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req)
{
// Resolve the service
var service = Bootstrapper.Container.GetInstance<ReceiveEventFunction>();
// Invoke the service
service.Run(req);
}
To complete the configuration, you will have to ensure the (new) static Bootstrapper.Container
field exists, and that ReceiveEventFunction
is registered:
public class Bootstrapper
{
public static readonly Container Container;
static Bootstrapper()
{
Container = new Bootstrapper().Bootstrap();
}
public static void Bootstrap(
IEnumerable<Assembly> assemblies = null, bool verifyContainer = true)
{
Container container = new Container();
container.Register<ReceiveEventFunction>();
... // rest of your configuration here.
}
}
Upvotes: 2