Azure / azure-functions-dotnet-extensions

Azure Functions .NET extensions
MIT License
71 stars 38 forks source link

DI sample code works when Function App is v2 but not v3 #40

Open nolanegly opened 4 years ago

nolanegly commented 4 years ago

I cannot get dependency injection to work in Azure Functions (documentation here) using a v3 Function App with .NET Core 3.1. (it will work locally but fails when deployed to Azure) The exact same code does work when deployed to a v2 Function App with .NET Core 2.1. The test code is forked from a sample maintained by a docs.microsoft.com contributor.

@fabiocav I apologize for how long these steps are, but I wanted to be sure the report was reproducible. Am I doing something wrong, or should I fallback to v2 for the next few weeks?

Create a function app instance

Log in to my subscription and create a new Function App

Basics

image

Note: even though I want to initially run this on .NET Core 2.1 to verify the sample code works, the only choice provided while doing initial setup is 3.1. We will adjust the runtime version after the function app instance is deployed.

Click “Next: Hosting”

Hosting

image

Click “Next: Monitoring”

Monitoring

image

Click “Review + create”

Review + Create

image

Click “Create”. Wait for the deployment to finish. Once the deployment finishes, choose “Go to resource”.

image

Configure the function app instance for .NET Core 2

We need to adjust several settings for the sample code to run properly.

Set runtime version

Choose “Function app settings”. Note the runtime version is set to 3. Click 2. Wait patiently.

image

Set bitness and always on

Go to Configuration. Choose the General settings tab.

image

Deploy the sample code with .NET Core 2

I forked the official sample from https://github.com/mike-urnun-msft/AzureFunkDI to https://github.com/nolanegly/AzureFunkDI in order to upgrade the .NET Core version and demonstrate the problem. I checked out the code to c:\dev\ resulting in a solution location of c:\dev\AzureFunkDI.

Build

On the master branch, with no code changes to the sample, publish the project. If the output directory c:\dev\stage already exists, delete it first. In a PowerShell prompt, navigate to the directory of the project and do dotnet publish --configuration “Release” --self-contained -r “win-x64” --output “c:\dev\stage”

image

Compress

After building the project, compress the output into a single zip for deployment. If the file c:\dev\stage\funkdi.zip exists, delete it first. In a PowerShell prompt, do `Compress-Archive /dev/stage/* -DestinationPath “c:\dev\funkdi.zip”

image

Deploy to Azure

To deploy the zip you must have installed the Azure CLI, available here if you don’t already have it.

If needed, log in to Azure CLI by typing az login in PowerShell.

Deploy the zipped payload to the function app by typing az functionapp deployment source config-zip -g fa-rg -n di-in-azure-func --src c:\dev\funkdi.zip

image

Verify the sample code works in v2

Navigate to the function app. On the left side, select “HttpTrigger”. Wait patiently. On the right side, select the “Test” tab.

In the bottom of the Test panel, the Output pane will say “Hello demo!” with a Status of “200 OK”. There will be no errors in the Logs pane.

image

Adjust code to .NET Core 3

On your local development machine, change branches from “master” to “upgrade-to-core-31” (again, this on the repository https://github.com/nolanegly/AzureFunkDI)

Observe the only changes are setting the project to .NET Core 3, Function App version 3, and the corresponding SDK dll to 3.0.5.

image

Deploy the sample code with .NET Core 3

Delete the previously built c:\dev\funkdi.zip file and c:\dev\stage directory. Publish the project with dotnet publish … as done previously. Compress the project with Compress-Archive … as done previously. Deploy the package with az functionapp … as done previously.

Configure the function app instance for .NET Core 3

In the portal, go to the “Function app settings”. Change the Runtime version to 3. Wait patiently.

image

Observe the sample code fails in v3

Navigate to the function app. On the left side, select “HttpTrigger”. Wait patiently. On the right side, select the “Test” tab.

EXPECTED

The same results we got in the section “Verify the sample code works in v2”

ACTUAL

In the bottom of the Test panel, the Output pane will have a Status of “500 Internal Server Error”. There will be a dependency injection failure in the error log.

System.InvalidOperationException : Unable to resolve service for type 'AzureFunkDI.IGreeter' while attempting to activate 'AzureFunkDI.HttpTrigger'. at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp,Type type,Type requiredBy,Boolean isDefaultParameterRequired) at lambda_method(Closure ,IServiceProvider ,Object[] ) at Microsoft.Azure.WebJobs.Host.Executors.DefaultJobActivator.CreateInstance[T](IServiceProvider serviceProvider) at C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\DefaultJobActivator.cs : 37 at Microsoft.Azure.WebJobs.Host.Executors.DefaultJobActivator.CreateInstance[T](IFunctionInstanceEx functionInstance) at C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\DefaultJobActivator.cs : 32 at Microsoft.Azure.WebJobs.Host.Executors.ActivatorInstanceFactory1.<>c__DisplayClass1_1.<.ctor>b__0(IFunctionInstanceEx i) at C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\ActivatorInstanceFactory.cs : 20 at Microsoft.Azure.WebJobs.Host.Executors.ActivatorInstanceFactory1.Create(IFunctionInstanceEx functionInstance) at C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\ActivatorInstanceFactory.cs : 26 at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker2.CreateInstance(IFunctionInstanceEx functionInstance) at C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs : 44 at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ParameterHelper.Initialize() at C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs : 846 at async Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsyncCore(IFunctionInstanceEx functionInstance,CancellationToken cancellationToken) at C:\projects\azure-webjobs-sdk-rqm4t\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs : 117 `

image

jwadaptivity commented 3 years ago

hey did you get a fix for this?

nolanegly commented 3 years ago

hey did you get a fix for this?

No, I had to rewrite the functions to work without DI. Fortunately I only had about five before I discovered the issue. I would still love to use DI in future work though.

jwadaptivity commented 3 years ago

@nolanegly I found in .csproj cause this for me. No idea why

RoyChase commented 3 years ago

This looks to be very similar to #45 which looks to be caused by having a UserSecretsId in the csproj. This is added in VS when setting up the publish profile to Azure.

@fabiocav is there a workaround or fix for this likely?

Absynthesis commented 3 years ago

This looks to be very similar to #45 which looks to be caused by having a UserSecretsId in the csproj. This is added in VS when setting up the publish profile to Azure.

We have the same issue

Hoping for update soon on this. I rather not have to static all our services.