Azure / azure-functions-core-tools

Command line tools for Azure Functions
MIT License
1.32k stars 434 forks source link

Update for compatibility with .NET 5 #2294

Closed jeffputz closed 2 years ago

jeffputz commented 3 years ago

While I can use the latest Microsoft.NET.Sdk.Functions package to build against .NET 5, the tools will not let you run it locally. Running a complied set of functions causes this this output in the tools:

System.Private.CoreLib: Could not load type 'System.Diagnostics.DebuggerStepThroughAttribute' from assembly 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
Value cannot be null. (Parameter 'provider')
jonsagara commented 3 years ago

I also got a runtime exception after upgrading to .NET 5:

Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.

I tried adding a PackageReference to my .csproj file, but I still get the same error. Any ideas?

TargetFramework: net5.0 .NET SDK: 5.0.100 VS 2019 Enterprise v16.8.0 Windows 10 20H2 (OS Build 19042.572) Core Tools Version: 3.0.2996 Function Runtime Version: 3.0.14916.0

laurence73 commented 3 years ago

experiencing same issue upgraded NetCore3.1 Azure functions to 5.0 - cannot debug locally

System.Private.CoreLib: Could not load type 'System.Diagnostics.DebuggerStepThroughAttribute' from assembly 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. Value cannot be null. (Parameter 'provider')

SoleCode commented 3 years ago

Same here Upgrade Azure Function .NET Core 3.1 to .NET 5 and getting this error:

Azure Functions Core Tools Core Tools Version: 3.0.2996 Commit hash: c54cdc36323e9543ba11fb61dd107616e9022bba Function Runtime Version: 3.0.14916.0

[2020-11-11T19:41:10.765Z] A host error has occurred during startup operation 'f070cd92-9072-4328-b7e3-9920d81ccbf7'. [2020-11-11T19:41:10.767Z] System.Private.CoreLib: Could not load type 'System.Diagnostics.DebuggerStepThroughAttribute' from assembly 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. Value cannot be null. (Parameter 'provider')

ajtatum commented 3 years ago

I'm receiving a similar error in Visual Studio after upgrading to VS 16.8.0 and trying to run a C# function, but for a different assembly.

Azure Functions Core Tools Core Tools Version: 3.0.2996 Commit hash: c54cdc36323e9543ba11fb61dd107616e9022bba Function Runtime Version: 3.0.14916.0

[2020-11-12T01:02:00.868Z] A host error has occurred during startup operation 'cd853b62-9e72-41ad-be3e-7066b55df568'. [2020-11-12T01:02:00.870Z] ProjectName: Could not load file or assembly 'Microsoft.Extensions.Configuration.Abstractions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.

vicinting commented 3 years ago

Similar problem for me. My entire journey:

  1. Just updated my Visual Studio to 16.8
  2. Created a new function and targeted .NET 5
  3. Added a startup class as mentioned in documentation
  4. Installed the packages Microsoft.Azure.Functions.Extensions & Microsoft.Extensions.Http
  5. Updated Microsoft.NET.Sdk.Functions to 3.0.11
  6. Ran the function and got the error below:

"Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified."

Invvard commented 3 years ago

Some of you could check this comment about the clean up feature and its workaround.

JPhillipBrooks commented 3 years ago

Some of you could check this comment about the clean up feature and its workaround.

Unfortunately adding <_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput> to the csproj made no difference for me. I'm still experiencing the same issues as everyone else here.

I've created a new Azure Function Project with a single HTTP Trigger to demonstrate the problem. Simply running the project demonstrates the issue. The repo is here.

anthonychu commented 3 years ago

The problems here are expected. The functions DLLs are loaded into the functions host, which is running on .NET Core 3.1. We do not support targeting net5.0 in a function app. We probably could do a better job surfacing the problem in Core Tools.

We're hoping to have a .NET 5 worker in preview by end of year.

jeffputz commented 3 years ago

@anthonychu yikes, that's a pretty serious adoption blocker for .NET 5. I don't have many projects that don't involve functions.

gustavf commented 3 years ago

Not clear from comments here if this is only a local issue related to the function emulator or if it is also a problem when you deploy? Can someone confirm either way?

jeffputz commented 3 years ago

@gustavf I haven't tried it, but I assume that if you deploy as self-contained, it doesn't matter what version you're building against. Keep in mind that I don't know for sure if the Functions SDK works with v5 either (now that is one of the most neglected projects in the ecosystem).

jonsagara commented 3 years ago

@gustavf I only tried it locally. Once it failed, I didn't try to deploy it.

codermrrob commented 3 years ago

Yes, same - would have been nice to see some information on this before I attempted to build .Net 5.0 function. Oh well, regressing...

rafaelcruz-net commented 3 years ago

I'm tried today. Same problem. Could not load type 'System.Environment' from assembly 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

jeffputz commented 3 years ago

@anthonychu any ETA on when we'll see v5 supported in Functions? It's a pretty big adoption blocker, and Azure is where we run .NET.

anthonychu commented 3 years ago

We announced an early preview of the .NET 5 worker.

We’ll work on updating the functions host for .NET 6.

We’ll also look into supporting some v5 frameworks such as Entity Framework Core 5 in the v3 worker, however we can’t make any promises there.

jeffputz commented 3 years ago

There are two things that I don't understand from that blog post. The first is that v5 has a "short" support cycle. A year seems like a long time, and it seems implied that if people weren't anxious to use the new bits, we wouldn't see support for it at all until v6.

The second thing is that, especially in this release cycle, v5 is so crazy good compatible that most projects allow us to simply update package references and run with it. I don't think it's been so mercifully easy in the history of .NET! The beta process is rich, public and predictable in timing, so my teams are able to get products updated ahead of time, and usually ship new bits running on the new fx within a few days. What's different about Azure Functions? Who do we have to appeal to to make sure you have the right human investment in staying current? I'm happy to make that noise! :)

anthonychu commented 3 years ago

I can share a bit on the decision making and prioritization process and how we got here. Back in the spring of 2020, we surveyed some folks that included Microsoft MVPs and discussed our options for .NET 5. The main takeaways were that we should build an out of process worker for .NET 5. And 2/3 of folks expressed that they plan to stay on .NET Core 3.1 instead of upgrading to .NET 5, so we did not feel there was overwhelming demand. Looking back, in hindsight, there was not a lot of solid details on .NET 5 and it made sense that folks were less excited about it at that time.

We also looked at runtimes like Node, where it is generally expected that platforms do not support non-LTS versions.

So over the summer, we started working on building an out-of-proc worker from scratch. It has taken us longer than expected to ship it. We had planned for the preview to land when .NET 5 GA'd, and that it would GA by end of 2020. We've slipped by a couple of months.

As for the assertion that 1 year is a long time, perhaps that's true. But we're also looking at what happens after that 1 year. There's a small 3-month window to ship a new version of the host with the .NET 6 GA bits, and migrate all customers off the .NET 5 host. We didn't feel that we should take a chance that we'd still need to run on .NET 5 after its end of life.

We want to provide timely support for LTS versions of .NET. We learned from .NET Core 3.1 that we need to more closely match the .NET release dates. We plan on updating the host to .NET 6 and having it available close to .NET 6 GA.

What we underestimated was the demand for non-LTS versions. We want to do better here. It's too early to tell what this will look like but I think will largely depend on the feedback on the .NET 5 worker.

jeffputz commented 3 years ago

I don't know if things have changed, but I recall in my MSDN community days that surveying MVP's for any reason was not reflective of what the broader world was after. :) And if 1/3 of customers were planning to move on up, at the scale that .NET operates at, that's a whole lot of people. If the mainline frameworks have revealed anything since going open source, it's that getting feedback early and often leads to better and far more predictable outcomes.

What I hear you saying is that you hear us, but you're non-committal to setting any expectations for v5, and that's discouraging. In my case, I'm trying to update one of my own OSS projects to keep up with the current bits, and I can't because of the Azure dependency, or specifically, the Functions dependency, which is a key part of the Azure ecosystem. Shared libraries are stuck at v3.1 because they have to be.

SRIVASTAVAABHISHEKGAURAV commented 3 years ago

Facing the below issue after upgrading from .NET 3.1 to .NET 5. Any workaround suggestions ?

Could not load type 'System.Environment' from assembly 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

kjartanvalur commented 3 years ago

Same here Could not load type 'System.Environment' from assembly 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.

OpusKrokus13 commented 3 years ago

@anthonychu - So why not carry forward what was in 3.1 until you have the next version ready? Support for functions is pretty essential to adoption.

phil-w commented 3 years ago

Has anyone figured out a work-around for this?

I tried working with my Function App as a separate "project", and down grading that to netcoreapp3.1 in the .csproj file. It builds for netcoreapp3.1, and there's no v5 stuff I can see in it, but it still fails with this precise error.

The "dog ate my homework" stuff isn't helping: does anyone know how to get past this problem, precisely?

Carl-Hugo commented 3 years ago

Has anyone figured out a work-around for this?

I tried working with my Function App as a separate "project", and down grading that to netcoreapp3.1 in the .csproj file. It builds for netcoreapp3.1, and there's no v5 stuff I can see in it, but it still fails with this precise error.

The "dog ate my homework" stuff isn't helping: does anyone know how to get past this problem, precisely?

For me, functions app works with 3.1. Look at the libraries that you loaded and make sure they don't have >3.1 dependencies.

bytemech commented 3 years ago

Good guide here for anyone looking for workarounds https://codetraveler.io/2021/02/12/creating-azure-functions-using-net-5/

jeffputz commented 3 years ago

Yikes, "workaround" is being generous.

Invvard commented 3 years ago

The wait is over : General availability: Azure Functions supports .NET 5 in production

Thanks @anthonychu

jeffputz commented 3 years ago

Cool, so what's the upgrade path? Docs show project->new.

rochapablo commented 3 years ago
$ CLI_DEBUG=1 func start --csharp --verbose
<TargetFramework>net5.0</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.11" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.4">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
  </ItemGroup>
[2021-03-17T14:32:37.933Z] A host error has occurred during startup operation 'fe3678ac-d56f-4397-b0ab-b16b24b79cae'.
[2021-03-17T14:32:37.933Z] System.TypeLoadException: Could not load type 'System.Environment' from assembly 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
[2021-03-17T14:32:37.933Z]    at Startup.Configure(IFunctionsHostBuilder builder)
[2021-03-17T14:32:37.933Z]    at Microsoft.Azure.Functions.Extensions.DependencyInjection.FunctionsStartup.Configure(WebJobsBuilderContext context, IWebJobsBuilder builder)
[2021-03-17T14:32:37.933Z]    at Microsoft.Azure.WebJobs.WebJobsBuilderExtensions.ConfigureStartup(IWebJobsStartup startup, WebJobsBuilderContext context, IWebJobsBuilder builder) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Hosting\WebJobsBuilderExtensions.cs:line 168
[2021-03-17T14:32:37.933Z]    at Microsoft.Azure.WebJobs.WebJobsBuilderExtensions.ConfigureAndLogUserConfiguredServices(IWebJobsStartup startup, WebJobsBuilderContext context, IWebJobsBuilder builder, ILoggerFactory loggerFactory) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Hosting\WebJobsBuilderExtensions.cs:line 131
[2021-03-17T14:32:37.933Z]    at Microsoft.Azure.WebJobs.WebJobsBuilderExtensions.UseWebJobsStartup(IWebJobsBuilder builder, Type startupType, WebJobsBuilderContext context, ILoggerFactory loggerFactory) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Hosting\WebJobsBuilderExtensions.cs:line 118
[2021-03-17T14:32:37.933Z]    at Microsoft.Azure.WebJobs.WebJobsBuilderExtensions.UseExternalStartup(IWebJobsBuilder builder, IWebJobsStartupTypeLocator startupTypeLocator, WebJobsBuilderContext context, ILoggerFactory loggerFactory) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Hosting\WebJobsBuilderExtensions.cs:line 211
[2021-03-17T14:32:37.933Z]    at Microsoft.Azure.WebJobs.Script.ScriptHostBuilderExtensions.<>c__DisplayClass7_0.<AddScriptHostCore>b__1(HostBuilderContext context, IWebJobsBuilder webJobsBuilder) in D:\a\1\s\src\WebJobs.Script\ScriptHostBuilderExtensions.cs:line 207
[2021-03-17T14:32:37.933Z]    at Microsoft.Extensions.Hosting.WebJobsHostBuilderExtensions.<>c__DisplayClass5_0.<ConfigureWebJobs>b__1(HostBuilderContext context, IServiceCollection services) in C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Hosting\WebJobsHostBuilderExtensions.cs:line 56
[2021-03-17T14:32:37.933Z]    at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
[2021-03-17T14:32:37.934Z]    at Microsoft.Extensions.Hosting.HostBuilder.Build()
[2021-03-17T14:32:37.934Z]    at Microsoft.Azure.WebJobs.Script.WebHost.DefaultScriptHostBuilder.BuildHost(Boolean skipHostStartup, Boolean skipHostConfigurationParsing) in D:\a\1\s\src\WebJobs.Script.WebHost\DefaultScriptHostBuilder.cs:line 59
[2021-03-17T14:32:37.934Z]    at Microsoft.Azure.WebJobs.Script.WebHost.WebJobsScriptHostService.BuildHost(Boolean skipHostStartup, Boolean skipHostJsonConfiguration) in D:\a\1\s\src\WebJobs.Script.WebHost\WebJobsScriptHostService.cs:line 542
[2021-03-17T14:32:37.934Z]    at Microsoft.Azure.WebJobs.Script.WebHost.WebJobsScriptHostService.UnsynchronizedStartHostAsync(ScriptHostStartupOperation activeOperation, Int32 attemptCount, JobHostStartupMode startupMode) in D:\a\1\s\src\WebJobs.Script.WebHost\WebJobsScriptHostService.cs:line 244
System.ArgumentNullException: Value cannot be null. (Parameter 'provider')
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Azure.Functions.Cli.Actions.HostActions.StartHostAction.RunAsync() in D:\a\1\s\src\Azure.Functions.Cli\Actions\HostActions\StartHostAction.cs:line 325
   at Azure.Functions.Cli.ConsoleApp.RunAsync[T](String[] args, IContainer container) in D:\a\1\s\src\Azure.Functions.Cli\ConsoleApp.cs:line 66
jeffputz commented 3 years ago

I'm satisfied with the outcome of this, using the instructions here.

However, the CLI tooling makes a template that won't work in the event that you want to get some settings from local.settings.json. That's not a bug, exactly, but you won't see it if you do something like this locally in your HostBuilder:

            var configuration = new ConfigurationBuilder()
                .SetBasePath(Environment.CurrentDirectory)
                .AddJsonFile("local.settings.json")
                .AddEnvironmentVariables()
                .Build();

It will break, because the template puts this in the .csproj:

    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>

The code wants to read the file, but then it isn't published, so the functions won't start (which is hard to diagnose since, suboptimally, real troubleshooting is only possible if you add Application Insights).

anthonychu commented 3 years ago

@jeffputz Anything that's in the Values section of local.settings.json should be made available in the environment, and environment variables are already included in the config (https://github.com/Azure/azure-functions-dotnet-worker/pull/333) if you use ConfigureFunctionsWorkerDefaults().

jeffputz commented 3 years ago

@anthonychu are you saying that in local environments you don't need to call out loading the json file?

anthonychu commented 3 years ago

@jeffputz Yeah I should have included a bit more. local.settings.json is specifically for use when running locally and is only loaded automatically when you run the app with Azure Function Core Tools. We exclude it from publishing because we recommend using app settings or Key Vault when running in the cloud.

ADH-LukeBollam commented 3 years ago

Is there a process I can follow to upgrade an existing 3.1 function to 5? Changing the target framework to .NET 5.0 and local.settings.json to dotnet-isolated is not enough to get it working

jeffputz commented 3 years ago

@anthonychu how then do you get access to configuration values in the context of the HostBuilder? I make some decisions in .ConfigureServices() based on configuration values (overriding certain implementations of certain interfaces based on configuration, for example).

jeffputz commented 3 years ago

I've been running functions for awhile in this new mode, and the timer functions periodically just die. The log shows Stopping JobHost, then a series of Stopping the listener... entries, and finally JobHost Stopped. If I hit one of the queue triggered functions, it seems to wake up and start processing again.

basklvn commented 3 years ago

FYI. Microsoft released Visual Studio support for .NET 5.0 isolated function apps on June 9th.

jeffputz commented 3 years ago

Unfortunately, not. I have this problem in https://github.com/Azure/azure-functions-dotnet-worker/issues/488 too. This is actually worse than before, because at least before it would launch the functions if not attach to them.

rochapablo commented 3 years ago

https://github.com/Azure/azure-functions-dotnet-extensions/issues/64