Azure / azure-functions-host

The host/runtime that powers Azure Functions
https://functions.azure.com
MIT License
1.94k stars 441 forks source link

Binding redirect support #992

Closed mamaso closed 6 years ago

mamaso commented 7 years ago

Per this customer issue:

http://stackoverflow.com/questions/40816285/azure-functions-with-nuget-packages-that-have-different-versions-of-the-same-dep#

fabiocav commented 6 years ago

Yes, this would only work with an App Service plan. We have some documentation on that process on the repo Wiki: https://github.com/Azure/azure-functions-host/wiki/Deploying-the-Functions-runtime-as-a-private-site-extension

We make all private site extensions available for all the releases (although, I just noticed that some of the later releases are missing it, so I just updated the last and will make sure the others have it as well). The latest can be found here: https://github.com/Azure/azure-functions-host/releases/tag/v1.0.11535

For the lack of a better word, I'll call this an "advanced" scenario. So it comes with a couple of warnings:

paulbatum commented 6 years ago

Thanks to @aarondcoleman for the thoughtful explanation of where he is at right now in regards to functions and this topic.

I wanted to say a few more words on this topic given that I manage the team at Microsoft that is ultimately responsible for fixing this issue that blocks so many potential users and is a significant source of frustration.

Firstly, its evident that we have done a poor job when it comes to communicating the status and scope of potential improvements in the area of assembly loading - for that I apologize. Many of you have commented that you were told a while back that "the assembly binding issue is going to be fixed". If this type of blanket statement is what you heard, then we screwed up. Because we've spent a significant amount of time investigation and evaluating potential improvements we can make but none of them were a single silver bullet that solves all the different variations of this problem in one fell swoop.

For example, take https://github.com/Azure/azure-functions-host/issues/1716. Some of you saw us punt this work repeatedly and expressed frustration (understandably). But let me be clear - the function assembly load context referred to in that issue does not apply to pre compiled functions (i.e. written as .cs files, compiled to dlls, typically from Visual Studio) - its used by csx based functions. So that issue describes work that would help a subset of csx cases unless the scope of the work was increased even further to have pre-compiled functions use that code path, a change we'd have to be pretty careful about to avoid regressions. I think people were watching that particular issue and asking "why is this slipping" without the context of whether it would have even helped their particular case (because the issue description did not go into enough detail - our fault).

The reality is that we have to be pretty careful about changes we make to V1. Many changes we thought were innocuous have caused unexpected regressions - for example take https://github.com/Azure/azure-functions-host/pull/2042. This change fixed issues that stopped users from using .NET Standard 2.0 libraries, but it broken our ngen image loading causing significant regressions in cold start performance. The one issue in this repo that has more comments than this one? Yeah it relates to cold start. Fixing this regression took weeks of investigation and ended up requiring us to wait for the .NET framework 4.7.1 update on App Service.

My point is that over the past several months we have become less enthusiastic about making improvements to assembly loading that only apply for V1, only apply for a subset of scenarios, and bear regression risk.

The commitment I'll make to you is that we will make concrete progress on this problem in Functions V2 and you'll see evidence of this before it goes into general availability. We will do in-depth writeups that explain the problem space and outline potential solutions and we'll solicit your feedback. For example, we're optimistic about using the .NET Core LoadContext as part of some of these solutions. Some of these solutions will be implemented before V2 goes GA and for others we'll have done enough homework to be confident that we can add them after GA without risk of breaking changes.

But please note that I said progress - not that we will magically solve every different variant of assembly loading issues that can exist. The fundamental challenges are:

  1. Our code runs in the same process as your code
  2. We have features that rely on an exchange of types between our code and your code (you specify you want your function to receive a JObject, so we have to instantiate one and pass it to you)
  3. For the consumption plan, we cannot give a user 100% control over the process and all the code that is loaded into the process as it would allow certain invariants we rely on to be broken. This is why functions is different to webjobs.
  4. We need to be able to sanely reason about whether a given change we make is potentially breaking. A scenario that scares us is where we code our runtime against Json.NET 10.x, we allow you to redirect everything to 11.x and then we later make a subtle change that relies on an API that changed between 10.x and 11.x. We deploy our change to prod and you get broken. We can't realistically test every different permutation of every different redirect if we give you full control, so the solution has to be more sophisticated than that.

We are going to need more data and your guidance on what specific scenarios to focus on fixing. In particular its not so helpful if you tell us "let me specify binding redirects" because that is not a scenario, its a potential solution to a set of scenarios. To get the ball rolling I spent a bit of time today putting together some truly trivial examples here. I did not think very hard about this format so it probably has issues but I am convinced we need to develop some sort of scenario catalog as it will help disambiguate the different issues at play.

Thanks for your patience. I'll be trying even harder than usual to be transparent about our efforts in this area and how we are prioritizing this work.

/cc @fabiocav to review in case I made any misstatements here.

owenneil commented 6 years ago

For clarification, of the 4 challenges you list there, are all of those still going to be true as part of V2 functions? Seems like #1 isn't true for other languages, so it seems less like a fundamental requirement. It seems like C# could be run out of process as well. Obviously there would need to be something to handle the messages and route them appropriately, but the process would be user owned at that point.

fabiocav commented 6 years ago

@owenneil the assembly load enhancements are not yet present in the V2 bits, so you won't see much of a difference with the current preview.

Running .NET workloads out-of-proc is an option we are indeed considering. Some of the work to pave the way has already been done with the language extensibility model in v2

BowserKingKoopa commented 6 years ago

@paulbatum Thanks so much for that write up. That really clarified some things for me. But yikes. This sounds really bad. I just wanted to run my .NET code in the cloud, and Functions can't do it. Not only is .NET not a first class citizen here, it doesn't really work at all.

I wish that had been presented clearer in the marketing material for Functions. I wish I'd been told "You are not the target audience for this product. You should stay in WebJobs. We do not have a serverless consumption priced solution for .NET yet." Instead I had to figure that out on my own. Painfully. This is the biggest dead end I've ever been down in the Microsoft ecosystem.

Maybe in the future a solution will be found with something like .NET Core LoadContext. Or maybe we just need a new product that provides serverless, consumption priced cloud functions for .NET developers (not for JavaScript, Java, or C# Script developers. For .NET developers.)

forki commented 6 years ago

@bowserkingkoopa time to look at lambda I guess.

viblo commented 6 years ago

@paulbatum Maybe you can update the function docs to explain this issue? For example, here is a comparison with webjobs where it would be very good to mention this issue: https://docs.microsoft.com/en-us/azure/azure-functions/functions-compare-logic-apps-ms-flow-webjobs Another place where it could fit is in the descriptions about how to write C# functions here: https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-class-library

For background I was also hit by this problem when trying out Functions. In general I think the biggest issue is communication. I can understand that there are hard technical challenges, but without proper communication it becomes 10x worse. I have had Azure support tell me to use functions to solve a scaling issue repeatedly even after I referenced this issue and how it prevent me to use Functions.

BowserKingKoopa commented 6 years ago

This is a debacle. At what point during the development of Microsoft’s flagship serverless computing platform did the engineers realize it didn’t work with Microsoft’s flagship development platform?

npiasecki commented 6 years ago

I've been watching this off and on since I first hit this with my log4net redirect problem back in May. At the time I remarked that the lack of binding redirect support was a ticking time bomb. It was fine for apps being written at the time, since I have rarely wanted to experience the pain of updating dependencies for an existing app unless I really, really needed to, but I thought that it would get worse for new projects as the rest of the dependencies moved on with newer versions, and that File > New Project looked more and more frozen in time. I briefly considered changing my Functions to PowerShell as I had also noted what @BowserKingKoopa did, that ironically .NET projects were adversely effected by the host simply being written in .NET.

We seem to have accepted that managing code dependencies is intractable from a maintenance perspective, so we just keep making copies of everything. First we started with bin deployment to at least make most dependency problems application wide instead of system wide, and with .NET Core we've moved up a level, and now we're copying the whole framework around. Then we sprinkle in some binding redirects with a hope and a prayer that some open source author hasn't gone nuts with breaking changes for the sake of "purity" in the latest release of their pet project. It's kind of crazy when you think about it, but rightly or wrongly, you basically just can't write non-trivial .NET code without binding redirect support.

I think the only way forward is to follow the language extensibility proposal and move the "C# language worker" and the functions host into separate processes. Adopt a stable suite of interfaces for the bindings that you support so that the functions host is always working against a stable interface. You can ship NuGet packages (installed with the consumer's code hosted in the language worker) that adapt these interfaces to the ever-changing versions of storage SDKs and other dependencies if you'd like to maintain the (admittedly cool) ability to bind to function parameters types declared in dependencies not controlled by the Functions team, like CloudBlockBlob.

I can't believe I'm writing this, but we've come full circle: we're talking about creating CGI on steroids.

The promise of Functions is amazing: just upload some code that conforms to said interface and poof! a magical runtime takes care of putting it on a box, running it in response to common events, scaling it out, failing over when the box blows up.

I think the Functions team built this system with a simpler intended use case. It was all lightweight functions in the cloud and the emphasis was coding in CSX files in the browser. They were surprised when lots of developers took one look at this platform and realized the potential to eliminate a lot of DevOps work. I mean, why even bother fooling around with containers and Kubernetes and Quartz.NET for scheduling when I can just zip up the darn thing and Azure does it all for me? The stopgap solution to addressing this sudden demand was hastily allowing precompiled functions, and developers clamored to use it, but the hosting model was not a good fit. As with most things with Azure, marketing went a little off the rails with it and the mismatch between what the docs say it does and what it actually does in a real project is very frustrating. Mistakes were made, and it's possible that Functions will end up supporting two different use cases: throwaway functions coded in the browser to meet a extract-transform-load need, and long-term "real" precompiled code that benefits from the hosting model.

My job is maintaining software for a warehouse. Every minute I'm managing dependencies, applying patches, poring over assembly versions, or upgrading code to work in a new operating environment, I'm not providing value. That's why I hope that V1 of the runtime, mistakes and all, will continue to run and be supported for quite some time. And when you move to an out-of-proc hosting model, not just for .NET but for all languages, you should be able to move all those V1 folks to the new hosting model with some middleware that transparently maps your new interfaces to the frozen-in-stone Storage SDK / Newtonsoft.Json dependencies that V1 is using. Then we never talk about it again.

Please keep at it, but I submit that the out-of-proc "language worker" model is the only way forward, and should be the team's primary focus. Fix it for .NET and you'll have a framework you can use for any other language you want to support.

StephenCleary commented 6 years ago

Here's an example of a use case that is broken today (using VS 15.6.1 and Azure Functions Tools 15.0.40215.0):

  1. File -> New -> Azure Function -> HTTP trigger (storage emulator, anonymous access).
  2. Install Newtonsoft.Json, since I always use it.
  3. Run the function. It starts the host just fine, but if I actually go to http://localhost:7071/api/Function1, then I get the error System.Private.CoreLib: Exception while executing function: Function1. FunctionApp2: Could not load file or assembly 'Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. Could not find or load a specific file. (Exception from HRESULT: 0x80131621). System.Private.CoreLib: Could not load file or assembly 'Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'.
  4. Spend some time trying to figure out why Newtonsoft.Json is not being found (?!?), and finally just throw my hands up and walk away from Functions.

There's a few "sub-problems" here:

  1. NuGet does a good job hiding the fact that the Functions app already has Newtonsoft.Json, so my own installation of it isn't necessary. (However, there are scenarios where users want to consume libraries that do use the latest version of Newtonsoft.Json).
  2. The error messages are misleading and confusing (though there's not much the Functions team can do about that). Especially in more complex binding scenarios. The Googleability for these errors is very low; on my first encounter, it took hours just to figure out what the problem was.
  3. The Functions host dependencies are undocumented, and this restriction/bug/whatever isn't prominent in the documentation.

More to the point, it's been my experience that several developers play with Functions for a bit, hit this issue fairly quickly, and then end up not adopting Functions. Right now the sense I get from the community is that Functions is just OK, because the end user has to be fine with staying on older versions of libraries (which is Not Good these days); and Functions is not sufficiently good at meeting the need of putting a simple API over some business logic in a preexisting library.

I agree that the out-of-proc model is the most likely long-term solution; however, there are some additional difficulties for .NET that don't exist (AFAIK) for other languages. Specifically, the bindings for .NET are amazingly awesome, and that very awesomeness is what would make out-of-proc .NET more difficult. At the very least, the each binding would need to be split into in-proc and out-of-proc components, with the communication between the two reduced to something absurdly simple, like a particular (strict) JSON schema, or a series of string name/value pairs. (It would have to be simple because the in-proc binding component would use the Functions host library versions, and the out-of-proc binding component would use the user dll library versions).

But even with this approach, it might not be fully possible. The simpler cases should work fine (e.g., in-proc monitors queue for new messages; out-of-proc does the message deserialization), but there's some advanced scenarios which may not work or may require much more cross-proc communication (e.g., binding a blob name to a field in a deserialized queue message). I don't use any of the more advanced functionality, so I'm not sure how far that rabbit hole goes. Also, bouncing back and forth between the in-proc and out-of-proc binding components could impact performance (especially if multiple bidirectional messages are required to fully bind all bindings). That said, this seems (to me) to be the solution that is most likely to work long-term.

paulbatum commented 6 years ago

@StephenCleary for the scenario you just described, I assume you did this selecting the V2 preview, as this is not the behavior you get on V1. Be aware that the current V2 code has ZERO behavior for managing this in that it does not even have binding redirects that we own (V1 has these).

We agree that out-of-proc is the long term solution to this problem, and you are correct that the richness of our .NET bindings represents a significant challenge.

We're actively working on the problem. I expect we'll be sharing a more detailed plan in a matter of weeks.

tomkerkhove commented 6 years ago

@paulbatum Are you saying this is fixed in Functions 2.0?

fabiocav commented 6 years ago

@StephenCleary, thanks for sharing your scenario and your always valuable feedback.

As Paul mentioned, a lot of work is happening and we intend to significantly improve this experience in V2. This will include (likely in a preview/limited state when V2 GAs) an out-of-proc execution model.

One thing I wanted to mention is that we're also actively working on documenting and generating lock files with all of the runtime dependencies (starting with V1, and eventually V2), which will help with one of the issues you brought up.

paulbatum commented 6 years ago

@tomkerkhove absolutely not. Also treating this issue as "fixed" or "not fixed" is too black and white. There are many different scenarios being rolled up here under one umbrella. When we start talking about things being "fixed", it will be on a case-by-case basis.

Ian1971 commented 6 years ago

Would an "easy" workaround be for azure functions to fork json.net at the version they are welded to and put it in a different namespace? It seems to me that a lot of problems people are having is the json.net dependency.

jorupp commented 6 years ago

While Newtonsoft.Json may be one of the common ones, it's far from the only one. I've had issues with WindowsAzure.Storage quite a bit too. Not sure how complete a solution that only covers a few libraries would be (and how much you'd have to change even to get that one).

paulbatum commented 6 years ago

@Ian1971 This has been discussed above already, but the short answer is that this would not help in a bunch of scenarios because these scenarios require an exchange of types (i.e. you ask for JObject in your code, and our code passes you one).

Ian1971 commented 6 years ago

Ok. Makes sense.

mrcarl79 commented 6 years ago

So I'm just checking if this issue is same one I'm experiencing so I don't create a new bug report.

I have installed a nuget package RazorLight -Version 2.0.0-beta1 which has a dependency for Microsoft.Extensions.DependencyModel and installs version 2.0.3 however I get the following error when trying to run the function:

Exception while executing function: Function1. RazorLight: Could not load file or assembly 'Microsoft.Extensions.DependencyModel, Version=2.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Could not find or load a specific file. (Exception from HRESULT: 0x80131621). System.Private.CoreLib: Could not load file or assembly 'Microsoft.Extensions.DependencyModel, Version=2.0.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.

From what I can research this seems to be because the Azure Functions extension I've installed on VS 2017 (all fully updated) already has Microsoft.Extensions.DependencyModel but at a lower version 2.0.0 which is causing a conflict.

Is my understanding of this correct and is there no current way to fix this or have a work around?

Thanks :)

Ian1971 commented 6 years ago

I'm new to this issue also but I think your understanding is correct. One workaround would be to fork RazorLight and build it yourself against 2.0.0

Szer commented 6 years ago

@mrcarl79 I had similar issue with Microsoft.AspNetCore.Mvc.Abstractions 2.0.2 Same error message. I changed my paket.dependencies like this: nuget Microsoft.AspNetCore.Mvc.Abstractions ~> 2.0.1.0 and everything works fine right now.

Just lower version with your package manager

mrcarl79 commented 6 years ago

Thanks @Szer and @Ian1971 as is often the case an unexpected workaround which is I found a different package which actually works better for our requirements DotLiquid which doesn't throw any dependency errors, which means my V2 function now works again (until next time!).

joeyeng commented 6 years ago

Just so I understand... if I have a working v1 Function deployed to Azure, say using 1.0.8 Functions Sdk for example. As long as I don't update any of the Nuget packages in the Function project itself or in a referenced project, then can I safely assume it will keep running without issues in the consumption plan?

paulbatum commented 6 years ago

@giemch Yes. We are as careful as possible to avoid making changes to what assemblies are loaded into V1 functions, such that if you got things working in Azure, they'll stay working. You don't need to regularly pull our latest nuget packages and deploy. If you are planning on updating some of your packages/dependencies, make sure you test that change in Azure in a separate environment to your prod env. This thread is about issues that come up during development or your first publish to Azure. Further questions about changes happening over time, after your app is successfully deployed and running in Azure, should be asked elsewhere.

fabiocav commented 6 years ago

We have added some information about this issue, details about how the binding process takes place in 1.0 and information about the enhancements being made to 2.0 in this wiki article.

We hope this helps add some clarity. Please continue to use this issue for any feedback/questions about what we covered there.

ciarancolgan commented 6 years ago

Hi @fabiocav - what happened to the Wiki page? It no longer seems to be available.... Thanks

brminnick commented 6 years ago

@ciarancolgan The wiki link works for me

ciarancolgan commented 6 years ago

@brminnick now it works for me again too. How strange. I was getting a 'You do not have permissions to update this wiki' toast message and redirected to the wiki home page. It just magically started working now that I cancelled the toast and tried again. shrugs

jboarman commented 6 years ago

@fabiocav

After reading the wiki article, it's not yet clear whether "binding redirect" support will be provided. There are other solutions mentioned (e.g., "Better isolation", "Out-of-proc worker"), but these don't share the same moniker as "binding redirect".

Without "binding redirect" support, there are a number of libraries that simply can't be used in an Azure Functions environment.

As a random real-world example, accessing Google Datastore from Azure Functions effectively can't be done ... it has to be in a webjob instead. Why? Google's dotnet dependencies are published at different times and depend heavily on semver conventions for resolving dependencies. Without "binding redirect" support, you will never have all your dependency versions perfectly aligned.

As Jon Skeet said in his response:

"assembly binding redirects really are pretty crucial these days" (emphasis added)

Can you clarify whether I'm just being too pessimistic here? Will these "solutions" in fact resolve the "binding redirect" problem? If not, how exactly is the proposed solution different from "binding redirect"? What common situations won't be addressed?

TonyHenrique commented 6 years ago

I am having a issue, I added this NuGet , when I run the function I get: Could not find the assembly 'Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' Please see https://github.com/Readify/Neo4jClient/issues/271

fabiocav commented 6 years ago

@jboarman you're correct that defining traditional assembly binding redirects is not something that will be directly supported by the runtime, but it would be in the out-of-proc model (as that model would be no different than any other .NET executable you deploy).

It's important to emphasize that, although the definition of binding redirects or access to the config file won't be exposed with the resolution and binding enhancements, the runtime will be handling the assembly unification for you (so your scenario, where assembly versions are not aligned should work without additional configuration). This is very much along the same lines as how .NET Core works, with a few differences to support Azure Functions specific cases.

The goal of this work is to address resolution and binding issues, and eliminate as much as possible the need for user-defined/configured binding redirects. In short, binding redirection will be supported, the runtime will handle unification, but there won't be an explicit configuration defined by the user.

If possible, I'd encourage you to put a concrete sample covering what you've mentioned together and PR that here, we can then dive into the specifics of your scenario, covering how things would work there and that scenario would also be part of the validation/testing we're performing with the enhancements in place.

georgeharnwell commented 6 years ago

Hi Guys, just want to first check I'm in the right place.

I'm writing an Azure function which uses Microsoft.WindowsAzure.Storage to check the status of rehydrating blobs when they move from Archive to Cold.

To do this, I need to check the StandardBlobTier field of the blob properties. I believe this is a fairly new property in the Microsoft.WindowsAzure.Storage nuget package and so I need to target the latest version.

I target version 9.1.0 in my project.json but I still get the error: 'BlobProperties' does not contain a definition for 'StandardBlobTier'. What version of WindowsAzure.Storage is automatically being loaded to Azure Functions environment and how do I override it?

Szer commented 6 years ago

@georgeharnwell I think it is Microsoft.WindowsAzure.Storage 7.2.1.0 according to this

georgeharnwell commented 6 years ago

Eugh, so I guess the next question is, is it overridable and if so, how?

Szer commented 6 years ago

@georgeharnwell that's the the whole point of this issue :) (You can't override it)

georgeharnwell commented 6 years ago

@Szer - so this SO answer isn't correct? In that uploading the correct version as a DLL in the bin folder doesn't work?

Szer commented 6 years ago

@georgeharnwell I think it is incorrect. You could use newer dll but it will throw MethodNotFoundException in runtime just like in your case.

jorupp commented 6 years ago

@georgeharnwell - I'm guessing you've defined your function to take in a reference to the blob (or the blob container/client), right? If you're doing that, the WebJobs SDK is in charge of creating that instance you're passed.

Try changing your code to open the blob yourself via a new CloudBlobClient (even if you have to read the URL/etc. off the blob that's passed in to find the exact blob you need). You may even try logging the assembly-qualified name of the type of the object you're passed in vs. what you get when you create it yourself to confirm what version of things is getting loaded.

I think the SO answer you referenced (and the other approaches discussed in this thread) will only work if your code is responsible for creating the instance - no matter what you do, the WebJobs SDK will always be creating v7.2.1.0 Microsoft.WindowsAzure.Storage objects.

georgeharnwell commented 6 years ago

@jorupp - thanks for the answer although I'm not entirely sure I understand. Maybe it'll help if I provide my code snippet:

```
var storageAccount = CloudStorageAccount.Parse(connString);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

// Retrieve a reference to a container. 
CloudBlobContainer container = blobClient.GetContainerReference(containerName);

// Retrieve reference to a blob.
CloudBlockBlob blockBlob = container.GetBlockBlobReference(blobName);

    //Fill blob properties
    await blockBlob.FetchAttributesAsync();

     if (blockBlob.Properties.StandardBlobTier.HasValue && blockBlob.Properties.StandardBlobTier.Value == StandardBlobTier.Cool)
     {
         return true;
     }

    return false;


Is this clear what I'm doing now?
jorupp commented 6 years ago

@georgeharnwell, yep, it's clear what you're doing, and my suggestion was to try doing exactly what you've done, so I guess it won't help :(

One of the ways you can set up a function is to accept the CloudBlockBlob object as an argument to your function, which I thought might have been the problem.

Only other thing I can think to try is overriding the normal assembly resolution and loading the version you want from the bin directory (something like https://github.com/Microsoft/BotBuilder/issues/2407#issuecomment-325097648), but for that to work, you'll have to make sure that your compile-time reference to Microsoft.WindowsAzure.Storage is 9.x or higher, you've deployed that to the bin directory (so it can find it), and that you put the code you pasted above in a separate method from where you set up the assembly resolve hook I linked to, which you then call after the hook is in place. This is because all types used in a method are loaded when the method is run for the first time, so you need to get the hook in place before the types load.

Yes, it's ugly, yes, the team knows this situation isn't good (scroll up this thread a bit), and yes, they've assured us they're working on it and that it'll get a bit better in v2 (https://github.com/Azure/azure-functions-host/issues/992#issuecomment-373799381), and much better when they add support for running your code in your own proc sometime after that.

georgeharnwell commented 6 years ago

Thanks for your answer @jorupp and it does sound tremendously hacky but I'll look into it and give it a go. I'd really like to retire my web job that is currently performing this so fingers crossed.

Milan03 commented 6 years ago

Getting conflicts trying to use "Google.Cloud.Firestore" Version="1.0.0-beta03" or any other beta version on "Google.Protobuf" Version="3.5.1". Getting exception Could not load file or assembly 'Google.Protobuf, Version=3.5.1.0. I believe this project uses version 3.3.0 but all the Google.Firestore betas seem to require >= 3.4.1. Any suggestions?

    <PackageReference Include="Google.Cloud.Firestore" Version="1.0.0-beta03" />
    <PackageReference Include="Google.Protobuf" Version="3.5.1" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.13" />
    <PackageReference Include="WooCommerceNET" Version="0.7.4" />
ThomasWeiss commented 6 years ago

Apologies in advance if that's a ditto of everything that's been said already, just trying to summarize the current situation and its implication.

Thanks in advance for any clarification!

HMoen commented 6 years ago

@ThomasWeiss, take a look at https://github.com/Azure/azure-functions-host/blob/dev/src/WebJobs.Script.Host/App.config We’ve been using it as a guide.

I understand from other threads that your question #1 would be a yes and #2 would be a no, but someone with better understanding should confirm.

paulbatum commented 6 years ago

@ThomasWeiss

First thing to note is that some of the answers depend on whether you are talking about functions V1 or functions V2.

Second thing to note is that functions V2 is still WIP so the answers might change in the future, while for functions V1 there is no further work happening in this area so the answers are likely to stay the same.

  1. In V1, you are not fully constrained to the versions of the libraries that the functions runtime uses but certain scenarios stop working when you reference a newer version. Take a look at this functions V1 example: https://github.com/paulbatum/functions-assembly-loading-catalog/blob/master/ReferenceNewerJsonNet/ReferenceNewerJsonNet/UseJObjectInResponse.cs

It has two functions that use a newer version of Json.NET. The function UseJObjectInResponseViaStringContent works because no exchange of types occurs. The function UseJObjectInResponseDirectly does not work because it relies on exchanging types.

This situation in V2 is improved - many scenarios that include an exchange of types now work even if you are using a different version of a given library.

  1. For V1, I prefer to point people to https://github.com/Azure/azure-functions-host/blob/v1.x/src/WebJobs.Script.WebHost/Web.config as the binding redirects there are actually the ones in play when you run on Azure.

  2. One a given version of functions goes GA, we try to be extremely careful about any dependency upgrades. Once your code is up and running in Azure, we intend for it to stay that way.

fabiocav commented 6 years ago

In addition to the Web.config link @paulbatum has linked to, we also have a lock file with all of the runtime's dependencies, and their versions, here: https://github.com/Azure/azure-functions-host/blob/v1.x/src/azurefunctions-v1-paket.lock

ThomasWeiss commented 6 years ago

Thanks @HMoen @paulbatum and @fabiocav. I should have clarified that I'm using v2 indeed.

devedse commented 6 years ago

Also running into this issue when using the Bot Framework together with Azure Functions. Would be helpful to get this supported.

Joehannus commented 6 years ago

We had some issues with Azure Functions using the Microsoft,Azure.Devices, Microsoft.Azure.Devices.Client and Newtonsoft libraries, in relation to using AMQP as communication protocol, and I got the advice to use binding redirects using the following link: https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/bindingredirect-element

I implemented this (using an app.config) in our azure function project. And it worked accordingly, solving all issues. I wonder though - is this a supported feature?

BowserKingKoopa commented 6 years ago

Any update on this? What's the current state of Azure Functions with regard to using the dlls I give it instead of crashing? https://github.com/Azure/azure-functions-host/wiki/Assembly-Resolution-in-Azure-Functions hasn't been updated in a while.