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

Add support for authoring Azure Functions as .NET Core class library #805

Closed
pscholtes opened this Issue May 17, 2018 · 52 comments

Comments

Projects
None yet
@pscholtes
Copy link

pscholtes commented May 17, 2018

Add support to the "Azure Functions and Web Jobs Tools" extension within Visual Studio for authoring Azure Functions as a .NET Core class library. This issue is a spin off from a conversation started in #686 and is possibly, semi-related to #790.

When creating a new Azure Function app, you must select between the versions "v1 (.NET Framework)" or "v2 (.NET Standard)".

  1. If v1 is selected, you can target any version of the .NET Framework <= 4.6.1
  2. If v2 is selected, you can target any version of .NET Standard <= 2.0

Neither option allows the resulting Azure Function project to target .NET Core 2.x.

Scenario
Given the following VS solution/project architecture for Company Xyz:

  • Xyz.Common .NET Core 2.x shared library leveraging EF Core and various 3rd party packages
  • Xyz.Web ASP.NET Core Web Application leveraging AspNetCore.All, EF Core, Controllers, etc.
  • Xyz.Functions v2 Azure Functions project with HTTP, timer, and queue triggers

Problem
When a project reference is added from Xyz.Functions to Xyz.Common Visual Studio generates a "project not compatible" build error as these two projects reference different frameworks (i.e. .NET Standard != .NET Core).

Reasoning
In a "real word" enterprise-level application, it's a very realistic expectation for a developer to centralize the logic for a specific processing routine and want to leverage that code from an IActionResult in a MVC app and a [TestMethod] in a MSTest project. Continuing with that approach, AF should allow a developer to leverage their .NET Core code from a Trigger as well.

@paulbatum

This comment has been minimized.

Copy link
Member

paulbatum commented May 17, 2018

Some of the discussion in this issue is relevant - it provides steps that can get a function app with target netcoreapp2.0 compiling, but not running:
Azure/azure-functions-vs-build-sdk#160 (comment)

This is the error you'll get if you try this:
image

It would be good to understand whether we expect to be able to get this working. I don't understand the details so I'm tagging @fabiocav.

@hanblee

This comment has been minimized.

Copy link

hanblee commented Jun 11, 2018

FYI, as mentioned in #836, AWS Lambda allows one to target netcoreapp2.0 (https://aws.amazon.com/blogs/developer/aws-lambda-net-core-2-0-support-released/).

@pscholtes

This comment has been minimized.

Copy link
Author

pscholtes commented Jun 12, 2018

Hey @paulbatum, in #836 (comment) you mention that more "investigation" is required for this issue. I am just curious, but is this issue in active discovery/development on the MSFT side? Do you have any updates or roadmap for support? Thanks!

@paulbatum

This comment has been minimized.

Copy link
Member

paulbatum commented Jun 12, 2018

We're not spending cycles on this at the moment but we intend to in the coming months.

@keesdewit82

This comment has been minimized.

Copy link

keesdewit82 commented Jun 25, 2018

This issue is pretty much holding me from using Azure functions. Please spend cycles on this. Its keeping developers with existing .NET Core libraries on the WebJob side.

@MisinformedDNA

This comment has been minimized.

Copy link

MisinformedDNA commented Jun 25, 2018

Since this won't happen for a few months, at least, could your libraries target .NET Standard instead? If not, what is blocking that?

@keesdewit82

This comment has been minimized.

Copy link

keesdewit82 commented Jun 25, 2018

Its too much impact compared to the worth of the improvement. Im not suddenly targeting my production libraries to .NET standard. Its a fundamental change which requires full application testing and staging. Not something I put on my sprint that easy.

@pscholtes

This comment has been minimized.

Copy link
Author

pscholtes commented Jul 19, 2018

I'm seeing that with version 15.0.40617.0 of the AF extensions, you can pick either the v1 (.NET Framework) or the v2 (.NET Core) project template. When v2 is selected the resulting project still targets the .NET Standard framework.

In tracking this issue I recall that this is more or less how the extensions worked when v2 was introduced (i.e. choose v2 (.NET Core), but the project targets Standard); however, this confusion of Core/Standard was first discussed in #686 with @soninaren where ultimately it was changed to read v2 (.NET Standard) in 15.0.40502.0.

The 15.0.40617.0 release notes state that:

The tools will run v2 Azure Functions locally against .NET Core 2.1.

@paulbatum not trying to understate the nuances/complexities of this, but can you please provide any updates or insights related to the aforementioned changes?

@paulbatum

This comment has been minimized.

Copy link
Member

paulbatum commented Jul 25, 2018

Hi @pscholtes, unfortunately I dont have much else to add right now. The VS tooling has been built and tested to use class libraries that target .NET Standard, and there are technical problems that need to be worked through to allow you to work with class libraries that target .NET Core. We want to investigate but its not sitting at the top of our list of must-fix issues so I have no progress to report at the moment.

@QuantechTP

This comment has been minimized.

Copy link

QuantechTP commented Aug 11, 2018

The situation described by pscholtes's "real-life application" is exactly what our company is facing. It would mean the world if the issue could be prioritized. We've been looking at the github issues for months now with no real update on this.

@sfmskywalker

This comment has been minimized.

Copy link

sfmskywalker commented Aug 13, 2018

I need Functions to target .NET Core as well.

In my case, I have a .NET Core class library that utilizes HttpClientFactory which today only exists in .NET Core. If I want to use Functions v2 and leverage this class library, it needs to target .NET Standard 2.0, which means managing HttpClient myself. Knowing all there is to know about HttpClientFactory, I really rather not :)

I wanted to look for a UserVoice idea on this, and turns out one does exist and is actually marked as "Completed"! But alas, although the title says "Support for NET Core", it was completed with support for NET Standard :(

@MisinformedDNA

This comment has been minimized.

Copy link

MisinformedDNA commented Aug 15, 2018

HttpClientFactory supports .NET Standard. See project file and NuGet. Hope this can unblock you for now.

@Tealons

This comment has been minimized.

Copy link

Tealons commented Aug 16, 2018

This also a blocker for us. Would be nice to get this fixed in the near future!

@keesdewit82

This comment has been minimized.

Copy link

keesdewit82 commented Aug 16, 2018

Please target .NET core so I can start using functions instead of workers. I have been waiting for months now. Thanks in advance!

@MisinformedDNA

This comment has been minimized.

Copy link

MisinformedDNA commented Aug 16, 2018

@keesdewit82 Why not use WebJobs? No one should have to use workers. ;) And conversions from WebJobs to Functions are more straightforward.

@MisinformedDNA

This comment has been minimized.

Copy link

MisinformedDNA commented Aug 16, 2018

@Tealons & @keesdewit82 Out of curiosity, what features of .NET Core are you using that prevents you from targeting .NET Standard?

@keesdewit82

This comment has been minimized.

Copy link

keesdewit82 commented Aug 16, 2018

@MisinformedDNA I have an existing .NET core solution. Changing my libraries to .NET standard would be a major change and would require full application testing. Too much for too little.

Btw, I meant WebJobs indeed, the one that runs in my App Service.

@Tealons

This comment has been minimized.

Copy link

Tealons commented Aug 17, 2018

@keesdewit82 @MisinformedDNA Exactly the same issue here with regard to the dependency.

@Securso

This comment has been minimized.

Copy link

Securso commented Sep 21, 2018

I am about to start developing a .NET Core class library, that I would like to use with ASP.NET Core websites and Azure Functions. Unfortunately, this creates problems because Azure functions only run with .Net Standard. I want to use .NET Core for performance reasons (this is important to me): including Span, Memory and the forth coming linker.
Today I have decided to go with .NET CORE, so Azure Functions are of little use to me.
I was going to put a lot of functionality into Azure Functions. Now, all I will use them for are simple timers for checking web sites are running OK and processing a few Azure Storage Queues, such as a critical error queue. The code in these functions will have to be minimal.
Six months ago, I would have said .NET Standard is the way to go. No longer, it is too dependent on other frameworks such as the .NET Framework and Xamarin. I read that the next release of the .NET Framework will not be implementing Span and Memory, so it will probably be a long time before they make it into .Net Standard.
Azure functions really are useful, unfortunately, the teams developing the functionality only seem to be interested in one small .NET library. They need to be able to run with all the .Net Frameworks.
Microsoft needs to sort this mess out.

@Tealons

This comment has been minimized.

Copy link

Tealons commented Sep 21, 2018

@Securso We decided to not use Azure function, but to create an implementation with IHostedServices. Maybe that's also a good alternative for you...

@MisinformedDNA

This comment has been minimized.

Copy link

MisinformedDNA commented Sep 21, 2018

@Securso The System.Memory package has the Span types for the .NET Framework, .NET Core and .NET Standard.

@Securso

This comment has been minimized.

Copy link

Securso commented Sep 22, 2018

I will be doing a fair bit of text parsing in my application.
Suppose I wish to parse at integer at offset 10 for a length of 3, in a string.
With .Net Core 2.1, I simply create a span for the characters and call the relevant Int parse method. The parse is done without a copy of the sub string being placed on the managed heap. The managed heap is not used.
As far as I’m aware, the other frameworks do not have the overload. If I used these, I would need to create a substring on the managed heap, and then parse that string, which is much slower.
Hence the need to use .Net Core 2.1.

@MisinformedDNA

This comment has been minimized.

Copy link

MisinformedDNA commented Sep 23, 2018

Yup, I know exactly what you are talking about and those types were added to the System.Memory package for .NET Framework 4.5+ and .NET Core 2.0. It was Core 2.1 at first, but now you can use them anywhere. They've also made changes to RyuJIT to increase performance for all frameworks.

@paulbatum

This comment has been minimized.

Copy link
Member

paulbatum commented Sep 24, 2018

@MisinformedDNA The new types were added in the package you are referring to but not the overloads on existing types, such as the one that @Securso mentioned (int.Parse)

@MisinformedDNA

This comment has been minimized.

Copy link

MisinformedDNA commented Sep 27, 2018

@paulbatum I'm confused about the recent GA announcement of v2 with regard to this issue. It says

.NET developers can now author functions using .NET Core 2.1.

Some of the documentation also uses .NET Core verbage, like

Runtime 2.x runs on .NET Core 2

Most of the considerations required in moving between versions are related to the language runtime changes listed above (for example C# moving from .NET Framework 4.7 to .NET Core 2).

In fact, the only place I see .NET Standard referenced, is when the documentation calls out the target framework, all other places I've found reference .NET Core.

So can we target .NET Core now or not?

@paulbatum

This comment has been minimized.

Copy link
Member

paulbatum commented Sep 27, 2018

I agree that the first quote you pulled is a little bit misleading. Right now the VS tooling makes it easy to run on .NET core 2.1 but "using" implies a little more (such as being able to use APIs that only exist in .NET Core 2.1).

I think there is no issue with the second quote you pulled though. When you write a V2 function its running on .NET Core 2.1.

@fabiocav

This comment has been minimized.

Copy link
Member

fabiocav commented Oct 11, 2018

The Microsoft.NET.Sdk.Functions package 1.0.23 was just published to Nuget. That version has the tooling changes to enable targeting netcoreapp2.1

Templates have not yet been updated, but to validate the new behavior, you can simply update the TargetFramework project property to netcoreapp2.1

Please let us know if you run into issues with that flow (also let us know if it works for you, as it would be good to get validation :) )

@brandonh-msft

This comment has been minimized.

Copy link
Member

brandonh-msft commented Oct 11, 2018

is it valid to be targeting core for something like a function app which is compiled as a DLL?? My understanding's always been if the code has an entry point it should target Core (vs Standard) whereas libs (aka DLLs) should be built on Standard.

@shibayan

This comment has been minimized.

Copy link

shibayan commented Oct 11, 2018

@fabiocav TargetFramework is changed to netcoreapp2.1 and debugging in Visual Studio, the following error will be displayed and functions not start.

image

Running with func.exe will work. but it is always an error from Visual Studio.

@fabiocav

This comment has been minimized.

Copy link
Member

fabiocav commented Oct 11, 2018

@shibayan does a simple build work for you? If not, can you share a build log with any errors you may find?

@brandonh-msft targeting netcoreapp2.1 is valid, and that would give you a class library that can be consumed by other .NET Core apps. With that, you would have access to .NET Core APIs not in .NET Standard, also be able to consume other .NET Core dependencies, but as you can expect, that would sacrifice compatibility. This is equivalent to picking the .NET Core Class Library template in VS.

@brandonh-msft

This comment has been minimized.

Copy link
Member

brandonh-msft commented Oct 11, 2018

@fabiocav 👍 but I feel it's worth clarifying that the current .Net Standard DLL a Function App is built in to today would also be consumable by a .Net Core app

@shibayan

This comment has been minimized.

Copy link

shibayan commented Oct 11, 2018

@fabiocav Yes. I just created Azure Function v2 and HttpTrigger using template in Visual Studio and changed TargetFramework to netcoreapp2.1.
It seems to be a Visual Studio error, but I could not find the log.

@brandonh-msft

This comment has been minimized.

Copy link
Member

brandonh-msft commented Oct 11, 2018

@pscholtes
I'm curious. Can you give me more detail on why you centralized your logic in to a .Net Core library instead of a .Net Standard one?

@paulbatum

This comment has been minimized.

Copy link
Member

paulbatum commented Oct 11, 2018

@brandonh-msft Most of the customers that I've talked to about this are targeting .NET Core because of the additional APIs that don't exist in .NET Standard.

@fabiocav

This comment has been minimized.

Copy link
Member

fabiocav commented Oct 11, 2018

Yeah, I was able to repro that.

While we investigate, can you change your project properties from project to executable for the launch option under Debug and use the following executable path: %localappdata%\AzureFunctionsTools\Releases\2.8.1\cli\func.exe and add host start to the arguments.

@shibayan

This comment has been minimized.

Copy link

shibayan commented Oct 11, 2018

Thanks! I can now be debugging from Visual Studio.

@pscholtes

This comment has been minimized.

Copy link
Author

pscholtes commented Oct 12, 2018

Hey @brandonh-msft! I believe at the time of this issue the latest .NET Standard version was missing critical API support for my application (maaaybe EFCore?). I honestly don't have a ton of working knowledge or experience with .NET Standard, so I likely didn't explore that avenue. I think I had incorrectly assumed that Standard would eventually go away and everything would be Core... but it's looking like we'll have both options for the foreseeable future?

I got the same "fatal error" prompt from VS2017 and the fix described by @fabiocav did the trick (though it's %LocalAppData% for those following along at home).

@fabiocav

This comment has been minimized.

Copy link
Member

fabiocav commented Oct 12, 2018

@pscholtes thanks for the update! I've corrected the typo above! :)

@fabiocav fabiocav closed this Oct 12, 2018

@fabiocav fabiocav reopened this Oct 12, 2018

@brandonh-msft

This comment has been minimized.

Copy link
Member

brandonh-msft commented Oct 12, 2018

@pscholtes fair enough, though even EFCore only takes .NetStandard as a dependency
image

I fully empathize w/ the confusion between Core and Standard so I'm trying to understand if it's a messaging/education issue or if there's a legit reason to create a library based on Core that I'm missing. This said, I did some research and did find a list of the missing namespaces from Standard that are present in Core and was a bit surprised at what I found (System.Buffers, for instance) but you're always free to bring those libs in separately (as EFCore does with System.Collections.Immutable (missing from Standard, present in Core), for example).

@fabiocav

This comment has been minimized.

Copy link
Member

fabiocav commented Oct 12, 2018

In addition to .NET APIs, we also have customers who wanted to use dependencies they were bringing in that only supported .NET Core, and investing in changing the target for those dependencies was impractical or impossible (e.g. they didn't own the dependency). This change unblocks those customers in Functions.

@pscholtes

This comment has been minimized.

Copy link
Author

pscholtes commented Oct 12, 2018

@brandonh-msft it's mostly messaging/education for me... when I see ".NET Standard" my brain interprets that as something akin to like .NET CF on a Pocket PC.

@gladitormaximus

This comment has been minimized.

Copy link

gladitormaximus commented Oct 25, 2018

Some of the discussion in this issue is relevant - it provides steps that can get a function app with target netcoreapp2.0 compiling, but not running:
Azure/azure-functions-vs-build-sdk#160 (comment)

This is the error you'll get if you try this:
image

It would be good to understand whether we expect to be able to get this working. I don't understand the details so I'm tagging @fabiocav.

Just an update on how I fixed this run time error - [Updated Azure Functions Web Jobs Tools from 15.8 to 15.10].

@colbroth

This comment has been minimized.

Copy link

colbroth commented Oct 26, 2018

Some of the discussion in this issue is relevant - it provides steps that can get a function app with target netcoreapp2.0 compiling, but not running:
Azure/azure-functions-vs-build-sdk#160 (comment)
This is the error you'll get if you try this:
image
It would be good to understand whether we expect to be able to get this working. I don't understand the details so I'm tagging @fabiocav.

Just an update on how I fixed this run time error - [Updated Azure Functions Web Jobs Tools from 15.8 to 15.10].

An update to Azure Functions and Web Job Tools version 15.10.2046.0 fixed this error for me. I was at a previous version of 15.10 and still received the error.

@paulbatum

This comment has been minimized.

Copy link
Member

paulbatum commented Oct 29, 2018

Folks, we released the tooling updates last week. The default experience for File -> New Project -> Azure Functions is now a .NET Core 2.1 class library.

image

image

If you get the error in the screenshot in the post from @colbroth above, make sure you update to the latest version of the Azure Functions and Web Jobs Tools.

Anyone tried it out? I'd like to close this issue but I was hoping to hear from a few of you on how well this is working before I do that :)

@paulbatum

This comment has been minimized.

Copy link
Member

paulbatum commented Oct 29, 2018

Also I should note that while I was talking about and screenshotting VS, all of this is true for Visual Studio Code as well :)

@mayoatte

This comment has been minimized.

Copy link

mayoatte commented Oct 31, 2018

@paulbatum I just tried this but i immediately ran into issues getting the Startup class into the extensions.json file. The known workarounds (build target etc.) don't work with .netcore 2.1

@fabiocav

This comment has been minimized.

Copy link
Member

fabiocav commented Oct 31, 2018

@mayoatbm can you open a separate issue with the details of your problem (your startup setup, details on which assembly you're applying the attribute to, etc.?)

@mayoatte

This comment has been minimized.

Copy link

mayoatte commented Nov 1, 2018

@fabiocav Done. Thanks.

@MisinformedDNA

This comment has been minimized.

Copy link

MisinformedDNA commented Nov 2, 2018

@paulbatum

When I tried creating a new project via "Recent project templates" on the
"Start page", I'm pretty sure I saw ".NET Standard". But when I clicked on "Create new project" and selected "Azure Functions" from the dialog, it said ".NET Core". I checked "Recent project templates" again and it now says ".NET Core". So either I read it wrong the first time, or there was some caching involved.

On 15.10.2046.0

@soninaren

This comment has been minimized.

Copy link

soninaren commented Nov 2, 2018

@MisinformedDNA When you go through the new project dialog box, it checks for an update to CLI and templates. If there is an update VS will start fetching the update and you will see a message at the bottom of the dialog box saying something like "Making sure all templates are up to date..." . Once that process is finished the message will be replaced with "refresh" link that will would have update the text in the new project dialog box.

However if you don't wait for the update to finish and click OK. It will use the current latest template on disk and will keep updating the templates in background. So the next time you open the templates you would automatically have latest which in this case is ".Net Core"

@paulbatum

This comment has been minimized.

Copy link
Member

paulbatum commented Nov 10, 2018

We haven't seen any major issues with this change so I'm closing this issue.

@paulbatum paulbatum closed this Nov 10, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment