BorisWilhelms / azure-function-dependency-injection

Dependency Injection for Azure Functions v2
https://blog.wille-zone.de/
MIT License
145 stars 45 forks source link

DI for Services in External Assemblies #13

Closed isaacrlevin closed 5 years ago

isaacrlevin commented 5 years ago

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?

BorisWilhelms commented 5 years ago

This behavior is correct. In https://github.com/isaac2004/AzureFunction-DI/blob/2cd1bbd952593df1333e8ba38c50a5cc488bb7b8/Functions/DependencySetup/Injection/InjectWebJobsExtension.cs#L23 you are creating a new ServieProvider and you can ony resolve services that are registered on that particular provider. Since you have not registered any Logger on that provider, it can not resolve it.

If you use my latest nuget package for DI, you can implement a ServiceProviderBuilder where you can get the LoggerFactory of the Host, so you can register and create Loggers. Example

    internal class ServiceProviderBuilder : IServiceProviderBuilder
    {
        private readonly ILoggerFactory _loggerFactory;

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

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

            services.AddTransient<ITransientGreeter, Greeter>();
            services.AddScoped<IScopedGreeter, Greeter>();
            services.AddSingleton<ISingletonGreeter, Greeter>();
            // Important: We need to call CreateFunctionUserCategory, otherwise our log entries might be filtered out.
            services.AddSingleton<ILogger>(_ => _loggerFactory.CreateLogger(LogCategories.CreateFunctionUserCategory("Common")));
            services.AddSingleton<LoggingGreeter>();

            return services.BuildServiceProvider();
        }
    }

I have pushed the example to https://github.com/BorisWilhelms/azure-function-dependency-injection/blob/master/src/ExampleFunction/Startup.cs

isaacrlevin commented 5 years ago

The issue I see here though is that dependencies take a generic ILogger vs ILogger. To be able to share that service between an ASP.NET Core app, I need to have ILogger.

BorisWilhelms commented 5 years ago

My example registeres and creates an ILogger and not the generic ILogger<T>.

isaacrlevin commented 5 years ago

I am sorry, I was hoping to get ILogger like ASP.NET Core is looking for