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

Azure functions dependency injection - error when referencing class library #1718

Closed
joseftw opened this issue May 14, 2019 · 14 comments
Closed

Comments

@joseftw
Copy link

joseftw commented May 14, 2019

I have a Azure Functions project that has a reference to a class library (netstandard 2.0).
The class library contains a reference to Microsoft.Extensions.DependencyInjection.Abstractions.
The class library has the following extension method:

using JOS.MyApp.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace JOS.MyApp.Application
{
    public static class ApplicationConfigurator
    {
        public static void AddApplication(this IServiceCollection services)
        {
              // Do stuff
        }
    }
}

My functions startup looks like this:
Startup.cs

using JOS.MyApp.Functions;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

[assembly: FunctionsStartup(typeof(Startup))]
namespace JOS.MyApp.Functions
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
              // It does not matter if this call is here or not, it crashes because of the reference to the class library anyway.
               builder.Services.AddApplication();
        }
    }
}

When the Azure Functions project references the class library, the following error occurs:

Azure Functions Core Tools (2.7.1158 Commit hash: f2d2a2816e038165826c7409c6d10c0527e8955b)
Function Runtime Version: 2.0.12438.0
SKipping 'FUNCTIONS_CORETOOLS_ENVIRONMENT' because value is null
[2019-05-14 20:10:32] Starting Rpc Initialization Service.
[2019-05-14 20:10:32] Initializing RpcServer
[2019-05-14 20:10:32] Building host: startup suppressed:False, configuration suppressed: False
[2019-05-14 20:10:32] A host error has occurred
[2019-05-14 20:10:32] JOS.MyApp.Functions: Method not found: 'Microsoft.Extensions.DependencyInjection.IServiceCollection Microsoft.Azure.Functions.Extensions.DependencyInjection.IFunctionsHostBuilder.get_Services()'.
Value cannot be null.
Parameter name: provider

If I remove the reference to the class library, the function app starts as expected.
So the problem appears to be that im using the Microsoft.Extensions.DependencyInjection.Abstractions package in my class library.

To Reproduce

Steps to reproduce the behavior:

  1. Create a new functions app
  2. Create a new class library
  3. Setup DI for your functions app as described here: https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection
  4. Add the same extension method as above to the class library
  5. Add a reference to the class library from the Azure Functions project
  6. Try to run the functions project

Expected behavior

The functions project starts without any issues.

Additional context

Host (useful for support):
  Version: 3.0.0-preview5-27626-15
  Commit:  61f30f5a23

.NET Core SDKs installed:
  2.1.602 [C:\Program Files\dotnet\sdk]
  2.1.700-preview-009597 [C:\Program Files\dotnet\sdk]
  2.1.700-preview-009601 [C:\Program Files\dotnet\sdk]
  2.1.700-preview-009618 [C:\Program Files\dotnet\sdk]
  2.2.202 [C:\Program Files\dotnet\sdk]
  2.2.203 [C:\Program Files\dotnet\sdk]
  2.2.300-preview-010046 [C:\Program Files\dotnet\sdk]
  2.2.300-preview-010050 [C:\Program Files\dotnet\sdk]
  2.2.300-preview-010067 [C:\Program Files\dotnet\sdk]
  3.0.100-preview5-011568 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.0.0-preview5-19227-01 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.0-preview5-27626-15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.0.0-preview5-27626-15 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
@joseftw
Copy link
Author

joseftw commented May 14, 2019

@VaclavElias
Copy link

VaclavElias commented May 14, 2019

Just a guess, can you mix your class library which is referencing Microsoft.Extensions.DependencyInjection.Abstractions 3.0.0-preview5.19227.9 with Azure Function netcoreapp2.1?

@MikaBerglund
Copy link

I remember that I had a similar problem, when referencing Microsoft.Extensions.DependencyInjection.Abstractions Nuget package directly. I resolved this by referencing only the Microsoft.Azure.Functions.Extensions package, and that package references the Microsoft.Extensions.DependencyInjection.Abstractions package too.

I tried with your repro you posted, and I got the same error your describe, but resolved it by removing the direct reference to Microsoft.Extensions.DependencyInjection.Abstractions from the ClassLibrary1 project, and added a reference to Microsoft.Azure.Functions.Extensions to that same class library.

@joseftw
Copy link
Author

joseftw commented May 15, 2019

Thanks @MikaBerglund.
I tried that yesterday as well and got it working, but unfortunately that's not a viable solution for me since my class library is used by multiple applications which are not Azure Functions, so I don't want it to have any Azure Functions specific references.

To me it feels like a bug, the Microsoft.Extensions.DependencyInjection.Abstractions package was created specifically for this scenario, to have one common abstraction.

What do you think? :)

@MikaBerglund
Copy link

Sure it feels like a bug, or at least an unwanted feature. At the end of the day, the Microsoft.Azure.Functions.Extensions package references exactly the same version of the Microsoft.Extensions.DependencyInjection.Abstractions as you had in your class library, so there should not even be any version conflicts.

@analogrelay
Copy link

At the end of the day, the Microsoft.Azure.Functions.Extensions package references exactly the same version of the Microsoft.Extensions.DependencyInjection.Abstractions as you had in your class library

Is that true? Looking at the sample, the class library references 3.0.0-preview5.19227.9 of Microsoft.Extensions.DependencyInjection.Abstractions but the Microsoft.Azure.Functions.Extensions package references 2.2.0 of that package.

This kind of MethodNotFoundException is exactly the kind of error I'd expect when mixing major/minor versions. Your class library is built against a newer version than is actually available on the Azure Functions runtime, so you are getting runtime errors. You can't cross the streams between 2.2 and 3.0.

@analogrelay
Copy link

Transferring to DI repo and area.

@analogrelay analogrelay transferred this issue from dotnet/aspnetcore May 15, 2019
@MikaBerglund
Copy link

Is that true? Looking at the sample, the class library references 3.0.0-preview5.19227.9 of Microsoft.Extensions.DependencyInjection.Abstractions but the Microsoft.Azure.Functions.Extensions package references 2.2.0 of that package.

The class library references version 3.0.0-preview5.19227.9 of the Microsoft.Extensions.DependencyInjection.Abstractions package. The function app MyApp references version version 1.0.0 of the Microsoft.Azure.Functions.Extensions, which in turn references Microsoft.Extensions.DependencyInjection v2.2.0, which then references version 3.0.0-preview5.19227.9 of Microsoft.Extensions.DependencyInjection.Abstractions.

So for both projects the same version of Microsoft.Extensions.DependencyInjection.Abstractions should be resolved, or?

@analogrelay
Copy link

Microsoft.Extensions.DependencyInjection v2.2.0, which then references version 3.0.0-preview5.19227.9 of Microsoft.Extensions.DependencyInjection.Abstractions.

That's not what the package manifest itself says: https://www.nuget.org/packages/Microsoft.Extensions.DependencyInjection

If you're looking in Visual Studio, it shows the resolved version, not the version specified in the dependency. When you have two package references in the dependency graph for the same ID, only one version is selected (the highest one generally) and used to satisfy both dependencies. This is generally good, but can lead to situations like this where you are referencing a 3.0 package with a breaking change and a dependency is built against the 2.2 package without that breaking change thus causing a break.

You should avoid crossing the version "streams" when referencing dependencies like this as breaking changes can bite you. Does the issue occur if you change your class library to depend on 2.2.0 of Microsoft.Extensions.DependencyInjection.Abstractions?

@MikaBerglund
Copy link

OK. I was under the wrong impression then.

@analogrelay
Copy link

Closing as it appears there is no actionable work here. It is possible to use the Abstractions library in this way, but you should generally stick the the lowest version supported on your platform to avoid these issues. There are cases where using a higher version will work, but your code may be built expecting certain methods/members to exist that don't.

@cfe84
Copy link

cfe84 commented Oct 7, 2019

✔️ Had the same issue. Just to clarify how to fix it for anyone who would get that out of the box following the instructions on DI with .net Functions - downgrade version of nuget package Microsoft.Extensions.DependencyInjection from 3.0.0 to 2.2.0

@rfcdejong
Copy link

✔️ Had the same issue. Just to clarify how to fix it for anyone who would get that out of the box following the instructions on DI with .net Functions - downgrade version of nuget package Microsoft.Extensions.DependencyInjection from 3.0.0 to 2.2.0

Worked for me after downgrading it in a class library as well

@shelbaz
Copy link

shelbaz commented Oct 15, 2019

✔️ Had the same issue. Just to clarify how to fix it for anyone who would get that out of the box following the instructions on DI with .net Functions - downgrade version of nuget package Microsoft.Extensions.DependencyInjection from 3.0.0 to 2.2.0

This worked for me too ! Thanks !!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants