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

Binding redirect support #992

Closed
mamaso opened this Issue Nov 27, 2016 · 166 comments

Comments

Projects
None yet
@fabiocav

This comment has been minimized.

Member

fabiocav commented Nov 28, 2016

This is a known limitation and, with the current design, not something that can be easily addressed. I'm adding a comment in the SO question as the root cause is not directly related to redirects.

@lindydonna lindydonna added this to the backlog milestone Nov 28, 2016

@lindydonna lindydonna added the feature label Nov 28, 2016

@paulbatum paulbatum changed the title from Better binding redirect support to Binding redirect support Mar 20, 2017

@jorupp

This comment has been minimized.

jorupp commented Mar 30, 2017

Is there another way to work around the issues binding redirects are usually used for? For example, I want to use the WebJobs nuget package, which requires 7.2.1 or higher of WindowsAzure.Storage. However, 8.1.1 is out, which updates a bunch of stuff, including adding support for block blob uploads. Then, when I declare a function as taking in a IQueryable<DynamicTableEntity>, I'm stuck - if I reference the 8.1.1 version to get the functionality I want, I get an error at function bind time that it DynamicTableEntity doesn't implement ITableEntity.

Or is there another way to achieve this besides binding redirect support?

@Blackbaud-MitchellThomas

This comment has been minimized.

Blackbaud-MitchellThomas commented Mar 30, 2017

Is this worth looking at, @jorupp?

https://blogs.msdn.microsoft.com/appserviceteam/2017/03/16/publishing-a-net-class-library-as-a-function-app/

The development experience using this approach has been so much better for me.

@jorupp

This comment has been minimized.

jorupp commented Mar 30, 2017

@Blackbaud-MitchellThomas - it has the same basic issue - no binding redirects. In fact, I hadn't run into the issue myself until I switched to that approach yesterday and updated all my nuget packages to the latest (since I had the package GUI to tell me about it). I got binding errors because the latest Microsoft.Azure.WebJobs needed an older version of WindowsAzure.Storage, and didn't recognize the 8.1.1 types as matching the 7.2.1 types it had loaded (since there was no binding redirect to force them to both load the 8.1.1 types).

@Blackbaud-MitchellThomas

This comment has been minimized.

Blackbaud-MitchellThomas commented Mar 30, 2017

That's good to know that it's still a potential gap. I have a project running in that format, and it cleared up my flavor of these issues. But my problem was that it was erroring looking for a given .dll and couldn't find it, so I had been able to figure out to supply it with the csx file.

@christopheranderson

This comment has been minimized.

Member

christopheranderson commented Apr 3, 2017

Blocked on this work: #1319

@jorupp

This comment has been minimized.

jorupp commented Apr 3, 2017

Could there be a way to work around this temporarily by providing the data on what version of an assembly to use in another form (ie. JSON file) and handling the AppDomain.AssemblyResolve event? Just thinking out loud here.

@danielmackay

This comment has been minimized.

danielmackay commented Apr 17, 2017

Is there any possible work around for this? We have just tried to migrate from web jobs to functions, but our application depends on Micosoft.Owin.Security 3.1.0.0, but internally Asp.Net Identity depends on Micosoft.Owin.Security 2.1.0.0. We cannot migrate to functions as we would like to until this is supported.

@RudyCo

This comment has been minimized.

RudyCo commented Apr 27, 2017

This is a major issue. How can Microsoft state that Azure Functions are ready for use in production environments with such limitation?

@fabiocav

This comment has been minimized.

Member

fabiocav commented Apr 28, 2017

@jorupp that is one possibility we have considered (we already perform a a fair amount of custom resolution). The the work planned in #1319 will address this in a better and more consistent (not Azure Functions specific) way.

In the meantime, an approach that will usually address this need is to place the assembly you wish to use in a bin folder, in the function folder. The runtime will use this location as a fallback when probing for assemblies.

@jnevins-gcm

This comment has been minimized.

jnevins-gcm commented Apr 28, 2017

That doesn't work. If a strong named assembly is already loaded into the appdomain by azure functions, it will always use that one before loading a new assembly and will then throw a manifest mismatch error for any strong named assembly

@jnevins-gcm

This comment has been minimized.

jnevins-gcm commented Apr 28, 2017

I think this is just a fundamental design problem in how azure functions were thought out. As a suggestion, the best thing I can think of is for azure functions to handle ALL assembly resolve events and have NO assemblies in any internal bin folders, loading all assemblies from byte arrays to ensure a "no load context" for all assemblies. Assembly resolve can then handle multiple versions of the same assembly loaded into a single app domain

@jnevins-gcm

This comment has been minimized.

jnevins-gcm commented Apr 28, 2017

Basically prevent any loading of any assemblies by the .net runtime itself, as assembly resolution in .net is a total mess anyway

@fabiocav

This comment has been minimized.

Member

fabiocav commented Apr 28, 2017

@jnevins-gcm that (as mentioned) doesn't work in all scenarios, but is a viable fallback for some. Much of what you suggest above is actually how things are handled (for example, private assemblies are loaded from byte arrays, without a load context, and side-by-side loading is supported), the Azure Functions assembly resolver establishes a function scoped context and bypasses the .NET loader in those scenarios, and the bin folder mentioned above is not the application bin folder, but the function scoped one (where assemblies are loaded using the method described above).

The details on how this work are a bit more complex, and there are scenarios where we must load assemblies differently, but if using private assemblies only, the workaround above works as described.

We are working on the longer term solution for this that will provide behavior consistent with a "regular" .NET application, but this is still a bit out.

@jnevins-gcm

This comment has been minimized.

jnevins-gcm commented Apr 28, 2017

I saw that work item. It seems like a very very bad idea. You're basically describing building a new remoting protocol.

The workaround doesn't work as described though, unless you're loading all the dlls ahead of time in the bin dirs irrespective of name, in which case one could name each conflicting dll according to its version. Is that the case?

@jnevins-gcm

This comment has been minimized.

jnevins-gcm commented Apr 28, 2017

*implementation not protocol

@fabiocav

This comment has been minimized.

Member

fabiocav commented Apr 28, 2017

@jnevins-gcm I'll try to put some documentation better describing this process and also the scenarios I'm referring to (I've been meaning to do that for a while).

For the out-of-proc issue, there are a lot of details missing there as well, and we're trying to update it so everything is out in the open and we can get more feedback, but the scope is significantly larger than just trying to run .NET in isolation.

I'll work with @christopheranderson to have more details on that issue so we can better discuss the approach.

@nickverschueren

This comment has been minimized.

nickverschueren commented May 1, 2017

I'm trying to reference a NetStandard library in my function and I'm getting:
mscorlib: Exception has been thrown by the target of an invocation. IoT.EuriSmartOfficeFunc: Could not load file or assembly 'System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies
This is probably due to this issue, because actually version 4.1.1.0 is deployed. Is there any way at the moment to get this assembly redirected?

@fabiocav

This comment has been minimized.

Member

fabiocav commented May 1, 2017

@nickverschueren what version of the runtime are you running against? (Here's how to check)

If you're running on anything below 1.0.10917, please restart your Function App and try again (if you find you're running on 10917, please also retry as it was just released)

@npiasecki

This comment has been minimized.

npiasecki commented May 2, 2017

After having played with a few small functions, I started porting one of our existing applications that has a component that's a Windows service that runs Quartz cron jobs over to Azure Functions as a precompiled assembly. I ran into an issue where one assembly is referencing log4net 2.0.8 but Microsoft.ApplicationInsights.Log4NetAppender is referencing log4net 2.0.5.

Since I can't do a binding redirect, I guess my options are to recompile the AI appender with 2.0.8, recompile the reference to downgrade to 2.0.5, or just give up and revert to WebJobs?

Recompiling in this particular case isn't a huge problem, but the lack of binding redirect support kind of makes Azure Functions a ticking time bomb when it comes to maintenance and gives me some serious pause. Is there any kind of timeline for when binding redirects will be supported?

@marcothz

This comment has been minimized.

marcothz commented May 2, 2017

+1

@flagbug

This comment has been minimized.

flagbug commented May 2, 2017

Without binding redirects, Azure Functions with precompiled assemblies is basically impossible to use, as soon as you want to use an external NuGet package

@flagbug

This comment has been minimized.

flagbug commented May 2, 2017

After some playing around, I've solved this by using ILRepack/ILMerge, to merge all the problematic dependencies into the main assembly. This seems to have solved the binding redirect issues

@devedse

This comment has been minimized.

devedse commented Jun 26, 2018

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

@Joehannus

This comment has been minimized.

Joehannus commented Jul 23, 2018

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

This comment has been minimized.

BowserKingKoopa commented Jul 25, 2018

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.

@fabiocav

This comment has been minimized.

Member

fabiocav commented Jul 25, 2018

@BowserKingKoopa we've been covering the updates on the preview release announcements. Most of the enhancements mentioned on that document are now live in the 2.0 preview. The vast majority of the binding issues have been addressed, with a couple of additional fixes coming as part of a larger set of changes to address storage dependencies.

Please give that a try and let us know if you run into any issues.

@MisinformedDNA

This comment has been minimized.

MisinformedDNA commented Jul 26, 2018

@BowserKingKoopa I've been using v2 with no binding problems.

@devedse

This comment has been minimized.

devedse commented Jul 30, 2018

@fabiocav, Is there a description available somewhere on how to do binding redirects with Azure Functions? Or will it all just magically work if there's a newer version of the DLL loaded then the one explicitly referenced?

@Joehannus

This comment has been minimized.

Joehannus commented Jul 30, 2018

@devedse
As I mentioned above we've had our share of binding issues as well - and I got the following link on how to do binding redirects in another thread (in this one: Azure/azure-amqp#110):
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 our issues. I don't know though whether this this a supported feature?

@fabiocav

This comment has been minimized.

Member

fabiocav commented Jul 30, 2018

@devedse there is no explicit binding redirect support. Redirects and unification are done implicitly by the runtime, using a few different sources of information depending on the model (e.g. your published artifacts, deps files and extensions registrations). So the short answer is that, in 2.0, it should "just work" without any additional steps.

@paulbatum

This comment has been minimized.

Member

paulbatum commented Jul 30, 2018

@Joehannus I would like to dig a little further into your question, as I'm surprised that you were able to resolve this type of problem with an app.config within your function app project, but it might be due to me overlooking some important factors.

I would prefer to not dive into the details here as this thread is already very long. Do you have a minimal, standalone repro that demonstrates how adding the app.config resolves the issue? If so, it would be great if you could file a separate issue (in this repo is fine) with the repro details and at me there so I can look further.

@Joehannus

This comment has been minimized.

Joehannus commented Jul 31, 2018

@paulbatum the reason I've tried this is that somebody on a different thread gave me that advice (Azure/azure-amqp#110). I've had lots of issues with the Azure.Devices libraries, either to get specific functions to be called, or even to get functions started at all due to binaries that could not be resolved - and after adding the app.config it seemed as if the starting issues were solved. But I've tried so many combinations of packages versions, to get multiple functions to run correctly, that solving the start issues just might have been coincidental, and that it was not due to the app.config.

To test this I've just installed the latest versions of all packages, and also removed the app.config. And the functions still run without issues. So it looks that it indeed was coincidental.

@MisinformedDNA

This comment has been minimized.

MisinformedDNA commented Jul 31, 2018

@fabiocav I can't remember any statement that this issue would ever be resolved on V1 and given that binding redirects work in V2, what is still left before we can close this issue?

@f2bo

This comment has been minimized.

f2bo commented Jul 31, 2018

While the V2 enhancements are welcome, they require that all dependencies be supported under .NET Core. We currently require dependencies that only target the .NET Framework and cannot be used in V2, as well as other dependencies that currently fail to load under V1 due its assembly resolution restrictions, which means that we cannot use either V1 or V2 successfully. We have a (brittle?) workaround for V1 based on AppDomain.AssemblyResolve, but there are still certain things that we cannot do, for example, use an ILogger instead of a TraceWriter in our Functions.

I have an open issue with more details here.

And a PR to the functions-assembly-loading-catalog here.

@paulbatum

This comment has been minimized.

Member

paulbatum commented Jul 31, 2018

For the purposes of the discussion on this particular github issue, I think it would be helpful to exclude scenarios that involve a library that does not support .NET Core. If you are curious about the advice I gave @f2bo, see this comment.

For further discussion of scenarios where Azure Functions V2 would run on .NET Framework and allow you to use libraries that don't support .NET Core, see here:
Azure/Azure-Functions#790

@paulbatum

This comment has been minimized.

Member

paulbatum commented Jul 31, 2018

@Joehannus thanks for getting back to us! I am really glad to hear that those packages are working for you on Functions V2 without any further configuration/changes.

@paulbatum

This comment has been minimized.

Member

paulbatum commented Aug 13, 2018

Just a small update. We are wrapping up changes that will address one of the remaining assembly loading issues that we are tracking for V2 GA which is providing flexibility around which version of the Azure Storage SDK you can reference. The release that will have this change has been announced here:
Azure/app-service-announcements#129

What this change does is move Azure Storage bindings into an extension, similar to everything else. This will allow for multiple versions of the storage extension to exist, each referencing a different major version of the Azure Storage SDK. You pick which version you reference in your function app based on your needs.

I should note though, we will be starting with Azure Storage SDK 9.x and do not plan on publishing RTM releases of this extension that target earlier major versions (such as 7.x or 8.x). We will of course publish a new version of the extension when the Azure Storage team releases a new major version of their SDK.

@Szer

This comment has been minimized.

Szer commented Aug 14, 2018

What this change does is move Azure Storage bindings into an extension, similar to everything else.

@paulbatum
I've just tested FSharp.Core 4.5.2 (newest release) and it works! (ValueOption, Map.TryGetValue)
AFAIK it was pinned in V2 runtime with 4.2.3 version.

Was it upgraded to latest or it works the same way as Azure Storage?
May I just upgrade FSharp.Core or Newtonsoft.Json as I wish?

@forki

This comment has been minimized.

Contributor

forki commented Aug 14, 2018

Regarding FSharp.Core: this was solved in: #2881 (comment)

@fabiocav

This comment has been minimized.

Member

fabiocav commented Sep 27, 2018

With Azure Functions 2.0 reaching General Availability, we have now completed the work to have this issue resolved for production workloads.

We truly appreciate all the reports, repros and patience while we worked on this during the preview.

@fabiocav fabiocav closed this Sep 27, 2018

@solvingj

This comment has been minimized.

solvingj commented Sep 27, 2018

Really impressive work!

holgerleichsenring added a commit to holgerleichsenring/AutofacOnFunctions that referenced this issue Oct 30, 2018

fix: fixed Azure Function assembly reference issues documented at Azu…
…re/azure-functions-host#992 via moving sample to Azure Functions GA version 1.0.23 and AutofacOnFunctions to WebJobs 3.0.0 instead of 3.0.0-rc1

holgerleichsenring added a commit to holgerleichsenring/AutofacOnFunctions that referenced this issue Oct 30, 2018

fix: fixed Azure Function assembly reference issues documented at Azu…
…re/azure-functions-host#992 via moving sample to Azure Functions GA version 1.0.23 and AutofacOnFunctions to WebJobs 3.0.0 instead of 3.0.0-rc1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment