Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrating Simple Injector in Azure Functions #536

Closed
aferrandiz1 opened this issue Apr 17, 2018 · 1 comment

Comments

Projects
None yet
2 participants
@aferrandiz1
Copy link

commented Apr 17, 2018

How can I use Simple Injector on Azure Functions?

@dotnetjunkie

This comment has been minimized.

Copy link
Collaborator

commented Apr 18, 2018

My advice is to use Azure Functions as Humble Objects being part of your Composition Root. 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.

Here's an example.

You can use the following static class that sets up the Container:

public static class DIConfig
{
    public static readonly Container Container;

    static DIConfig()
    {
        Container = new Container();
        
        // Example registrations
        Container.Register<ILogger, AzureLogger>(Lifestyle.Singleton);
        Container.Register(typeof(IHandler<>), typeof(IHandler<>).Assembly);
        
        Container.Verify();
    }
}

Using the DIConfig class, you can let your Azure function call into the Container to resolve a service and invoke it with the Function's input arguments:

[StorageAccount("AzureWebJobsStorage")]
public class CardGenerator
{
    [FunctionName("GenerateCard")]
    public static void GenerateCard([QueueTrigger("%input-queue%")] GenerateCard command)
    {
        // Resolve the service
        var service = DIConfig.Container.GetInstance<IHandler<GenerateCard>>();
        
        // Invoke the service
        service.Handle(command);
    }
}

So instead of injecting dependencies into the Azure function, dependencies are simply injected into the service implementation, as you are used to do. For instance:

public class GenerateCardHandler : IHandler<GenerateCard>
{
    private readonly ILogger logger;
    public GenerateCardHandler(ILogger logger)
    {
        this.logger = logger;
    }
    
    public void Handle(GenerateCard command)
    {
        // This is where your original Azure Function logic would sit.
        // In a sense, this IS your function.
    }
}

If you set up your application design cleverly, e.g. by introducing generic abstractions such as the IHandler<T>, you can simplify many tasks, such as:

  • Registering all 'function' component implementations in a single call to Register, as shown above.
  • You can easily wrap cross-cutting concerns, like the usual validation and tracing, in a way that prevents polluting all Azure Functions.

You can even simplify your Azure Function code by introducing a simple method in the DIConfig class:

public static void Handle<TCommand>(TCommand command) =>
    Container.GetInstance<IHandler<TCommand>>().Handle(command);

This reduces the Azure Function to the following:

[FunctionName("GenerateCard")]
public static void GenerateCard([QueueTrigger("%input-queue%")] GenerateCard command) 
    => DIConfig.Handle(command);

I hope this helps.

Repository owner deleted a comment from aferrandiz1 Apr 19, 2018

Repository owner deleted a comment from aferrandiz1 Apr 19, 2018

Repository owner locked and limited conversation to collaborators Apr 19, 2018

Repository owner deleted a comment from aferrandiz1 Apr 19, 2018

@dotnetjunkie dotnetjunkie changed the title Use simpleinjector on Azure Function Integrating Simple Injector in Azure Functions Apr 19, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.