Giter Site home page Giter Site logo

azure-function-dependency-injection's Introduction

Dependency Injection Extensions for Azure Functions v2

About

This repo contains binding extensions for dependency injection in Azure Function v2. Out of the box Microsoft.Extensions.DependencyInjection is used for dependency injection, but it is possible to use any IoC container that implements the IServiceProvider interface (for example Autofac).

How to configure

The dependency injection bindings are available as a nuget package. Once the package is added to function project, a WebJobsStartup is needed to register and configure the dependency injection bindings.

This is an example WebJobsStartup class

using ExampleFunction;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Willezone.Azure.WebJobs.Extensions.DependencyInjection;

[assembly: WebJobsStartup(typeof(Startup))]
namespace ExampleFunction
{
    internal class Startup : IWebJobsStartup
    {
        public void Configure(IWebJobsBuilder builder) =>
            builder.AddDependencyInjection(ConfigureServices);

        private void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<ITransientGreeter, Greeter>();
            services.AddScoped<IScopedGreeter, Greeter>();
            services.AddSingleton<ISingletonGreeter, Greeter>();
        }
    }

}

The nuget package contains two extension methods to register the dependency injection extensions.

AddDependencyInjection(this IWebJobsBuilder builder, Action<IServiceCollection> configureServices)

This configures the extension using the Microsoft.Extensions.DependencyInjection container. Services can be registered in the configureServices action.

AddDependencyInjection<TServiceProviderBuilder>(this IWebJobsBuilder builder) where TServiceProviderBuilder : IServiceProviderBuilder

This configures the extension to use what ever IoC container is returned from the Build method of the IServiceProviderBuilder implementation. It also gives access to other components, e.g. the configuration.

Example that uses Autofac

public class AutofacServiceProviderBuilder : IServiceProviderBuilder
{
    private readonly IConfiguration _configuration;

    public AutofacServiceProviderBuilder(IConfiguration configuration) => _configuration = configuration;

    public IServiceProvider Build()
    {
        Debug.WriteLine(_configuration["Setting"]); // Get a setting from the configuration.

        var services = new ServiceCollection();
        services.AddTransient<ITransientGreeter, Greeter>();
        services.AddScoped<IScopedGreeter, Greeter>();
        services.AddSingleton<ISingletonGreeter, Greeter>();

        var builder = new ContainerBuilder();
        builder.Populate(services); // Populate is needed to have support for scopes.

        return new AutofacServiceProvider(builder.Build());
    }
}

Using the extension

Once the extension is registered and configured dependencies can be injected using the Inject attribute on a function.

Example

[FunctionName("Greeter")]
public static IActionResult Run(
    [HttpTrigger(AuthorizationLevel.Function, "get")]HttpRequest req,
    [Inject]ITransientGreeter transientGreeter,
    [Inject]IScopedGreeter scopedGreeter,
    [Inject]ISingletonGreeter singletonGreeter,
    ILogger logger)
{
    logger.LogInformation("C# HTTP trigger function processed a request.");

    var result = String.Join(Environment.NewLine, new[] {
        $"Transient: {transientGreeter.Greet()}",
        $"Scoped: {scopedGreeter.Greet()}",
        $"Singleton: {singletonGreeter.Greet()}",
    });
    return new OkObjectResult(result);
}

Azure Deployment

Currently there is an issue when publishing your function application that the required extensions.json is not created correctly. The issue is discussed here. Luckily there is a workaround for this: Just copy the Directory.Build.targets file into your Azure Functions project, this will then create the correct extensions.json file.

azure-function-dependency-injection's People

Contributors

boriswilhelms avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

azure-function-dependency-injection's Issues

Microsoft.Azure.WebJobs.Host: Error indexing method

Microsoft.Azure.WebJobs.Host: Error indexing method 'ApiQueue.Run'. Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'dbService' to type IDbService. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. config.UseServiceBus(), config.UseTimers(), etc.).
[01/18/2019 21:58:03] Function 'ApiQueue.Run' failed indexing and will be disabled.

DI for Services in External Assemblies

I have an example of DI that I cannot get to work with the new version of WebHost. Here is my scenario.

I have a service in a .NET Standard library and am injecting it just fine into my function. I want to be able to inject an instance of ILogger or ILoggeeFactory into this service as well. However the dependency fails at the Service level. Here is a repo that fails.

https://github.com/isaac2004/AzureFunction-DI

Have you tried something like this?

Inject HttpRequest

I have services that depend on IHttpContextAccessor so that certain HTTP Headers and claim data can be accessed. Is there any way to configure DI for some form of the current HttpRequest?

'IFunctionInvocationFilter' is obsolete

Severity Code Description Project File Line Suppression State
Warning CS0618 'IFunctionInvocationFilter' is obsolete: 'Filters is in preview and there may be breaking changes in this area.'

Seems to be obsolete

Nuget package?

Hi. I was wondering if you were going to publish a nuget package for this?

durable functions - fanInFanOut

What is wrong with this code?
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage.Blob;

namespace VSSample
{
public static class BackupSiteContent
{
[FunctionName("E2_BackupSiteContent")]
public static async Task Run(
[OrchestrationTrigger] IDurableOrchestrationContext backupContext)
{
string rootDirectory = backupContext.GetInput()?.Trim();
if (string.IsNullOrEmpty(rootDirectory))
{
rootDirectory = Directory.GetParent(typeof(BackupSiteContent).Assembly.Location).FullName;
}

        string[] files = await backupContext.CallActivityAsync<string[]>(
            "E2_GetFileList",
            rootDirectory);

        var tasks = new Task<long>[files.Length];
        for (int i = 0; i < files.Length; i++)
        {
            tasks[i] = backupContext.CallActivityAsync<long>(
                "E2_CopyFileToBlob",
                files[i]);
        }

        await Task.WhenAll(tasks);

        long totalBytes = tasks.Sum(t => t.Result);
        return totalBytes;
    }

    [FunctionName("E2_GetFileList")]
    public static string[] GetFileList(
        [ActivityTrigger] string rootDirectory,
        ILogger log)
    {
        log.LogInformation($"Searching for files under '{rootDirectory}'...");
        string[] files = Directory.GetFiles(rootDirectory, "*", SearchOption.AllDirectories);
        log.LogInformation($"Found {files.Length} file(s) under {rootDirectory}.");

        return files;
    }

    [FunctionName("E2_CopyFileToBlob")]
    public static async Task<long> CopyFileToBlob(
        [ActivityTrigger] string filePath,
        Binder binder,
        ILogger log)
    {
        long byteCount = new FileInfo(filePath).Length;

        // strip the drive letter prefix and convert to forward slashes
        string blobPath = filePath
            .Substring(Path.GetPathRoot(filePath).Length)
            .Replace('\\', '/');
        string outputLocation = $"backups/{blobPath}";

        log.LogInformation($"Copying '{filePath}' to '{outputLocation}'. Total bytes = {byteCount}.");

        // copy the file contents into a blob
        using (Stream source = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
        using (Stream destination = await binder.BindAsync<CloudBlobStream>(
            new BlobAttribute(outputLocation, FileAccess.Write)))
        {
            await source.CopyToAsync(destination);
        }

        return byteCount;
    }


    [FunctionName("HttpStart")]
    public static async Task<HttpResponseMessage> Run(
        [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{E2_BackupSiteContent}")] HttpRequestMessage req,
        [DurableClient] IDurableClient starter,
        string functionName,
        ILogger log)
    {
        // Function input comes from the request content.
        object eventData = await req.Content.ReadAsAsync<object>();
        string instanceId = await starter.StartNewAsync("E2_BackupSiteContent", eventData);

        log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

        return starter.CreateCheckStatusResponse(req, instanceId);
    }
}

}

Failure to start when using external assembly

First of all thanks for this sample repo and the awesome article. I think your approach is the best I've found so far to cover the lack of DI on Az Functions.

I was trying to make your code reusable across multiple functions without having those files on every function project.

Got your sample code and moved it to its own assembly:

image

After that, I made the InjectConfiguration class abstract. That way, I was thinking that each function project would have a class that inherit from it and implement RegisterServices(IServiceCollection services) by adding its own dependencies.

Then the problem start... The host fail to start:

Run: Microsoft.Azure.WebJobs.Host: Error indexing method 'CreateProfileFunction.Run'. Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'tokenManager' to type TokenManager. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. config.UseServiceBus(), config.UseTimers(), etc.).

I've made several tests and for whatever reason, the host only load the IExtensionConfigProvider and the rest of the types if they are on the same function assembly. So we had to add link references to the files so they build with the same assembly.

Did you tried to do that? I can't see on your code anywhere hardcoded something related to local assembly or something that may led to this scenario.

Again, thank you for helping with this... I really appreciate that.

Singletons vs transient vs scoped

Is it possible to retrieve non scoped dependencies via the inject attribute? It looks like, the dependencies directly injected into the function are always scoped and will be destroyed after function execution had been left.

Not working when Deploying to Azure

It works locally running on Runtime version: 2.0.12115.0 (same as Azure) and Microsoft.NET.Sdk.Functions Version="1.0.22" but not In Azure

Error indexing method 'XXXXXX.Run' Cannot bind parameter 'worker' to type IXXXXXX.. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. config.UseServiceBus(), config.UseTimers(), etc.).

Unable to do constructor/property injection on a non static azure function

Azure Functions V2 has its own mechanism of DI that allows constructor/property injection. If i use this extension I'm able to use the Autofac DI features, and I'm able to do method injection, but it appears that property/constructor injection stops working.

Is possible to have the better of "the two worlds"?

Error Deploying to Azure

This is working fine when debugging on my machine, but I'm getting the following error when deploying a function using this package to Azure:

Error indexing method 'PurgePdfsFunction.Run' Cannot bind parameter 'processor' to type PurgePdfsProcessor. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. config.UseServiceBus(), config.UseTimers(), etc.). ย 

Any idea what I'm doing wrong?

Inject ILogger<T> or ILogger?

Is it possible to wire up ILogger or ILogger<T> injection? I tried the following, and while Thing got successfully injected with an ILogger<Thing>, using it doesn't actually produce any logs.

services.AddLogging();
services.AddSingleton<IThing, Thing>(sp => new Thing(sp.GetService<ILogger<Thing>>()));

Support IFunctionsHostBuilder initialization

Microsoft updated a way to register startup actions for Azure Functions v2. Now instead of IWebJobsBuilder we should use IFunctionsHostBuilder, so extension methods from this library cannot be used anymore with latest version of Azure Functions.

Code would not change at all, just new type to apply extension method to should be added.

Injecting to referenced assemblies

Does this approach will inject dependencies to referenced assemblies. For example if Greeter also was expecting a dependency, will it work?

Doesn't work with version 1.0.19 of Microsoft.NET.Sdk.Functions

I just want to start by saying thanks for an excellent solution that really helped me out!

The other day version 1.0.19 of the SDK was released, and I immediately ran in to problems .

The solution to these problems is to install an update to the VS2017 tools (forced on me today), and to install Microsoft.Azure.WebJobs.Extensions.Storage 3.0.0-beta8. It seems that this is working for other users but it breaks your DI solution!

The problem seems to be that they have removed the Config property of the ExtensionConfigContext used in your InjectionConfiguration class.

I have had a go at sorting it myself but made no progress; so I would really appreciate any help or pointers you could give?

Logging scopes seems to be not populated on Autofac container

I'm new on Azure Functions, and I've tried to use Autofac as the container of DI on the application.

There are some services there are registered automatically by the function on the .Net DI like for example the logging providers.

When I tried to use ILogger abstraction of Microsoft, I had an issue that was logging nothing on my custom classes, that were resolved by the Autofac, but all functions were able to log properly since that ILogger is resolver by .Net DI.

So I assume that services registered .Net DI are not on Autofac!
I've registered some manually to get Console logs and ApplicationLogs example:

public class WebJobsStartup : IWebJobsStartup
{

	public void Configure(IWebJobsBuilder builder) =>
	 builder.AddDependencyInjection<AutoFacServiceProviderBuilder>();
}
public class AutoFacServiceProviderBuilder : IServiceProviderBuilder
{
	private readonly IConfiguration configuration;

	public AutoFacServiceProviderBuilder(IConfiguration configuration)
		=> this.configuration = configuration;

	public IServiceProvider Build()
	{
		// Had to install:
		// - Microsoft.Extensions.Logging.Console 
		// - Microsoft.Extensions.Logging.Debug 
		// - Microsoft.Extensions.Logging.ApplicationInsights 
		
		var services = new ServiceCollection();
		services.AddLogging(l => l.AddConsole()
		.AddDebug()
		// Had to insert the ApplicationInsights key manually because was not working using the EnviromentVariable
		// check here: https://stackoverflow.com/questions/50717398/whats-the-difference-between-appinsights-instrumentationkey-configured-by-azure
		.AddApplicationInsights("Insert-AI-Key")); 
		
		var builder = new ContainerBuilder();
		builder.RegisterType<SingletonService>().As<ISingletonService>().SingleInstance();
		
		builder.Populate(services);
		return new AutofacServiceProvider(builder.Build());
	}
}

The problem is that I had to find out about those Extensions (AddLogging with all the providers) and scopes seem to be not working.
When I log using the ILogger on custom function comparing to the ILogger on function it misses some valuable information such as:

  • OperationId is empty (should be same as the function)
  • OperationName is empty (should be same as the function)
  • OperationParentId is empty (should be same as the function)
  • CouldRoleName is different from the function
  • CouldRoleInstance is different from the function
  • SDKVersion is different from the function

The most importante was to get the same OperationId as the function, since I want to correlate logs to the function call, so I have a way of tracking issues.

Any Idea why this is not working? I think is because probably since I need to manually program ApplicationInsights telemetries & scopes since they are not being populated on Autofac.

So my final questions are:

  • There is a way to populate the Services registered by the Function On Autofac, and will this solve my logging issues?
  • Which alternative can I use to solve the logging issues? (registering more stuff "manually"?)

Failure to deploy to Azure even with correct extensions.json

Good morning,

Thanks for a great library !!!

I'm trying to deploy my function to azure, it's working fine locally.

I've included the targets file and can see the updated extensions file in the bin folder on build.

However, when I deploy to Azure I get the Error indexing method 'XXXXXX.Run' Cannot bind parameter 'worker' to type IXXXXXX.. Make sure the parameter Type is supported by the binding. error

Any ideas appreciated.

Binding Issue with Extension prevents Function indexing

I am using the version 1.0.1 of this Nuget package in my .NET Core V2 Azure Function App to help with dependency injection and am running into an issue.

My Function app is to allow an HTTP upload of an image, and write it to blob storage and some associated meta-data to CosmosDb using the MongoDb Driver. I setup the WebJobStartup.cs class and used the '[Inject]' attribute on the interfaces I was trying to inject into the UploadFile.cs function class's Run method. See the source code.

When I run my function I get the following error:

[3/26/2019 1:34:03 PM] Error indexing method 'UploadImage'
[3/26/2019 1:34:03 PM] Microsoft.Azure.WebJobs.Host: Error indexing method 'UploadImage'. Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'cosmosDbClient' to type ICosmosDbClient. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).

Is there more that I should be doing with WebJobStartup.cs? Another obvious issue with my program? Or an issue with this project itself?

Dependency Injection built in to Azure Functions

Microsoft released Dependency Injection functionality recently which is built on top of the ASP.NET Core Dependency Injection Features. What advantages and disadvantages does providing this solution using Attributes provide their functionality does not?

Is one or the other better performing? Is this faster cold boot? Is there functionality missing/provided by the other? What does compatibility look like with different IoC Containers, or package dependencies?

http://aka.ms/functions-di-docs

Not working with Entity Framework 2.2

Adding DB context when Microsoft.EntityFrameworkCore.SqlServer v2.2.1 is used raise this error during app start:

A host error has occurred
Willezone.Azure.WebJobs.Extensions.DependencyInjection: Method not found: 'Microsoft.Extensions.DependencyInjection.IServiceCollection Microsoft.Azure.WebJobs.IWebJobsBuilder.get_Services()'.

When downgrade to EF v2.1.4 then register DB context is OK.

How to use Unity Service Locator?

We are having issue registering unity service locator in InjectConfiguration. Here's the code for Initialize method:

IUnityContainer container = new UnityContainer();
// Register ISomeService
var locator = new UnityServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => locator);
context.AddBindingRule<InjectAttribute>().Bind(new InjectBindingProvider(locator));

When in azure function we try to resolve as:

ServiceLocator.Current.GetInstance<ISomeService>();

It gives error "Service locator must be set". @BorisWilhelms

IConfigurationBuilder not working on mac

Hi

Thanks for sharing this library, its great!

I'm getting the following error when I try to run a Function App (v2) that works perfectly on my work PC, but not on my Mac.

OrpheusAPI: Method not found: 'Microsoft.Extensions.Configuration.IConfigurationBuilder Microsoft.Extensions.Configuration.FileConfigurationExtensions.SetBasePath(Microsoft.Extensions.Configuration.IConfigurationBuilder, System.String)'.

I'm running:
Azure Functions Core Tools (2.0.3)
Function Runtime Version: 2.0.12115.0

In the startup output I get see the following line:

IServiceProviderBuilder
Exception thrown: 'System.MissingMethodException' in Willezone.Azure.WebJobs.Extensions.DependencyInjection.dll

Any thoughts on what I'm doing wrong?

Do I need to do anything specific to get it to work on a mac?

If I hard code the connection string a comment out the IConfigurationRoot section it'll run but won't inject a logger.

WebjobsStartup.cs

using OrpheusAPI;
using OrpheusAPI.Data;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Hosting;
using Microsoft.Azure.WebJobs.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using Microsoft.EntityFrameworkCore;
using Willezone.Azure.WebJobs.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;

[assembly: WebJobsStartup(typeof(Startup))]
namespace OrpheusAPI
{
    internal class Startup : IWebJobsStartup
    {
        public void Configure(IWebJobsBuilder builder) =>
            builder.AddDependencyInjection<ServiceProviderBuilder>();
    }

    internal class ServiceProviderBuilder : IServiceProviderBuilder
    {
        private readonly ILoggerFactory _loggerFactory;

        public ServiceProviderBuilder(ILoggerFactory loggerFactory) =>
            _loggerFactory = loggerFactory;

        public IServiceProvider Build()
        {
            var services = new ServiceCollection();
           IConfigurationRoot config = new ConfigurationBuilder()
            .SetBasePath(Environment.CurrentDirectory)
            .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables()
            .Build();

            var connection = config.GetConnectionString("SqlConnectionString");
      
            // Important: We need to call CreateFunctionUserCategory, otherwise our log entries might be filtered out.
            services.AddSingleton<ILogger>(_ => _loggerFactory.CreateLogger(LogCategories.CreateFunctionUserCategory("Common")));
            services.AddDbContext<OrpheusContext>(options => options.UseSqlServer(connection));
            services.AddSingleton<IOrpheusRepository, OrpheusRepository>();

            return services.BuildServiceProvider();
        }
    }
}

What the aim of Task.Yield() here?

Hi!

First of all: many thanks for your awesome blogpost and this sample.
It made my usage of Azure function so much easier (with additional boilerplate but so much easier to use afterwards).

Just wondering: what the aim of the await Task.Yield() call in InjectBinding class?

Why do we need it?

Did you faced any issue without it?

Thanks !

Access to IConfigurationRoot when registering services

Hi Boris,

Thanks for the code and useful blog post.

When I register some services, I need to be able to use a connection string from a configuration object. I found a good article by Jon Gallant that describes the new way to build an IConfigurationRoot object. However, that approach relies on a ExecutionContext object, which I don't is available in InjectConfiguration.

Do you have any ideas how a can do this?

Not working with Microsoft.Extensions.DependencyInjection v2.2.0

This may be a duplicate of #21, although that doesn't capture the impact.

We've just updated our project to .NET Core 2.2 / EF Core 2.2, which means the datalayer class library our Functions project references now has a dependency on Microsoft.Extensions.DependencyInjection >= 2.2.0

This causes the following error on startup:

[17/12/2018 14:51:49] A host error has occurred
[17/12/2018 14:51:49] Willezone.Azure.WebJobs.Extensions.DependencyInjection: Method not found: 'Microsoft.Extensions.DependencyInjection.IServiceCollection Microsoft.Azure.WebJobs.IWebJobsBuilder.get_Services()'.
Value cannot be null.
Parameter name: provider

This prevents the function from starting.

If I downgrade the data layer back to 2.1.x libraries, the error goes away. If I then add an explicit reference to Microsoft.Extensions.DependencyInjection v2.2.0 to the functions project, it comes back, so it looks like this is the culprit.

For reference, both the Function project and the class library it's referencing are netstandard2.0. My local functions runtime is 2.0.12210.0, while Azure is running 2.0.12246.0 - same issue seen in both.

Not working with TimerTrigger functions

Somehow the Inject attribute isn't binding for a function that is triggered by a TimerTrigger - I get an error saying the runtime cannot bind the parameter.

I will fork the code and try to find the issue.

Binding fails with target frameworks netcoreapp 2.1 and 2.2

This package works fine when I target netcoreapp2.0. But when I target anything above that I get
Microsoft.Azure.WebJobs.Host: Error indexing method 'UploadImage'. Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'cosmosDbClient' to type ICosmosDbClient. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).

Add support for public property injection

Would it also be possible to add support for public property injection via annotation?

Like

[Inject]
public ISingletonGreeter SingletonGreeter;

[FunctionName("Greeter")]
public static IActionResult Run(
    [HttpTrigger(AuthorizationLevel.Function, "get")]HttpRequest req, ILogger logger)
{
    logger.LogInformation("C# HTTP trigger function processed a request.");

    return new OkObjectResult(SingletonGreeter.Greet());
}

Not working with netcoreapp2.1?

My function app is targeting netcoreapp2.1 - is it supposed to work with that?

I'm getting the error:

[29-Oct-18 14:09:22] Error indexing method 'WebhookProcessor.Run'
[29-Oct-18 14:09:22] Microsoft.Azure.WebJobs.Host: Error indexing method 'WebhookProcessor.Run'. Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'cc1' to type ICC1. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).

My project file looks like this:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <AzureFunctionsVersion>V2</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="3.0.1" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.23" />
    <PackageReference Include="Willezone.Azure.WebJobs.Extensions.DependencyInjection" Version="1.0.1" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

Startup class:

using MyApp.Functions;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Hosting;
using Microsoft.Azure.WebJobs.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using Willezone.Azure.WebJobs.Extensions.DependencyInjection;

[assembly: WebJobsStartup(typeof(Startup))]
namespace MyApp.Functions
{
	internal class Startup : IWebJobsStartup
	{
		public void Configure(IWebJobsBuilder builder) =>
				builder.AddDependencyInjection<ServiceProviderBuilder>();
	}

	internal class ServiceProviderBuilder : IServiceProviderBuilder
	{
		private readonly ILoggerFactory _loggerFactory;

		public ServiceProviderBuilder(ILoggerFactory loggerFactory) =>
				_loggerFactory = loggerFactory;

		public IServiceProvider Build()
		{
			var services = new ServiceCollection();

			services.AddTransient<ICC1, CC1>();

			return services.BuildServiceProvider();
		}
	}

	public interface ICC1
	{
		int MyProperty { get; set; }
	}

	public class CC1 : ICC1
	{
		public CC1()
		{
			MyProperty = 42;
		}
		public int MyProperty { get; set; }
	}
}

My function Run method:

[FunctionName("WebhookProcessor")]
public static async Task Run(
	[QueueTrigger("webhooks")] CloudQueueMessage queueMessage,
	[Table("webhooks")] CloudTable webhooksTable,
	[Blob("webhooks", FileAccess.ReadWrite)] CloudBlobContainer webhooksContainer,
	[Inject]ICC1 cc1,
	ILogger logger)
{
}

I have copied Directory.Build.targets into the folder of my project file.

Any ideas?

Logging from the Startup class

Hi all,

Thanks @BorisWilhelms for work - it's awesome. It makes working with Azure functions much more bearable. ๐Ÿ˜‚

My scenario:

I'm registering a database client (IMongoDatabase). As part of that registration, I'm mapping entities to (known) collections. If a collection does not exist, the code throws an exception.

How can I log this exception? It's essentially inside the private void ConfigureServices(IServiceCollection services) function and only have access to services.

Any ideas?

Much appreciated,
Prabu

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.