Azure Function, EF Core, Can't load ComponentModel.Annotations 4.2.0.0
Asked Answered
R

5

23

I have created several .Net Standard 2.0 libraries, tested the execution via a console application, as well as several tests - all is good.

Move over to azure function, and get the following run-time error: enter image description here

I then try to download that specific version into the API Function project: enter image description here

I'm using Visual Studio Version 15.7.0 Preview 5.0. I have updated the Azure Function to 4.7... as the console and test projects are - and those work.

Been at this a far too many hours.. so I'm hoping the resolution isn't something crazy. Ef Core 2.1.0-rc1-final is also in the mix. Using data annotations for Required, MaxLength, NotMapped.

Error in graphic says: Microsoft.EntityFrameworkCore: Could not load file or assembly 'System.ComponentModel.Annotations, Version=4.2.0.0

Rattlebrained answered 15/5, 2018 at 4:38 Comment(5)
try adding <PropertyGroup> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType> </PropertyGroup> in your csproj fileSirmons
What the version of your function, v1 or v2?Valina
Not sure how to tell about V1 or V2, just created it via VS 2017. Also the Property Group in the project didn't do anything.Rattlebrained
What is the target framework of your Azure Functions project? As you mentioned about I have updated the Azure Function to 4.7, I assumed that you targeted .NET Framework 4.7 and this is about the Azure Functions V1. I also created my Net Standard 2.0 class library and created my DbContext, I both referenced it under Azure Functions V1 (.net framework) and Azure Functions V2 (.net core) project and I found that both projects could work as expected.Mazur
Can you share your .csproj file or show the bin folder?Kwei
C
32

I would suggest running this function below once you start your Azure Function. It will redirect any assembly to an existing version.

public class FunctionsAssemblyResolver
{
    public static void RedirectAssembly()
    {
        var list = AppDomain.CurrentDomain.GetAssemblies().OrderByDescending(a => a.FullName).Select(a => a.FullName).ToList();
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    }

    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        var requestedAssembly = new AssemblyName(args.Name);
        Assembly assembly = null;
        AppDomain.CurrentDomain.AssemblyResolve -= CurrentDomain_AssemblyResolve;
        try
        {
            assembly = Assembly.Load(requestedAssembly.Name);
        }
        catch (Exception ex)
        {
        }
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
        return assembly;
    }

}
Cf answered 9/6, 2018 at 17:42 Comment(4)
Great, that worked! However, i suppose, this would have an effect on every function within the same function app i suppose?Effectuate
I am not clear as to how you are running this. I have tried it as the first line of a functions Run(...) method, and in a static constructor on the functions class, but it doesn't seem to get called during the build?Hydrolytic
Yes, that's exactly what I'm doing - running it on Run(...) or the constructor. It is not supposed to be called during build, it's a runtime issue, so it gets only called then.Cf
Note: This will only redirect the packages installed in the project in which the method is called. For example, if you call FunctionsAssemblyResolver.RedirectAssembly() in a "Services" project, it won't change the packages in an "Infrastructure" project, even if they're added as a reference. Having said that, THANK YOU! I've tried so many solutions for this dumb problem and this is the one that worked.Koralle
S
8

I followed the instructions here:

https://codopia.wordpress.com/2017/07/21/how-to-fix-the-assembly-binding-redirect-problem-in-azure-functions/

And added the following redirect:

"BindingRedirects": "[ { "ShortName": "System.ComponentModel.Annotations", "RedirectToVersion": "4.2.1.0", "PublicKeyToken": "b03f5f7f11d50a3a" } ]"

NOTE: Its not v 4.5.0.0 ... Its actually 4.2.1.0.

Sidras answered 9/6, 2018 at 4:23 Comment(2)
Note the important note. There are multiple versions that are actually AssemblyVersion 4.2.1.0Interpolation
Your note saved my life! I changed the binding redirect in web.config and everything works fine. Thank you very much.Pilsen
O
6

The accepted response will cause a CPU leak due to the += if it is misused, and will grind your function app to a halt. If you are using IoC, it is better to use a singleton. Here:

public class FunctionsAssemblyResolver
{
    static FunctionsAssemblyResolver()
    {
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    }

    // At least one static member needs to be invoked in order to execute the static constructor,
    // but it will only run the constructor once.
    public static void StaticInstance() { }

    private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        var requestedAssembly = new AssemblyName(args.Name);
        try
        {
            // Feel free to resolve any other assemblies, but this will take care of Annotations
            return requestedAssembly.Name == "System.ComponentModel.Annotations"
                ? Assembly.Load(requestedAssembly.Name)
                : null;
        }
        catch
        {
            // do nothing
        }

        return null;
    }
}

To use, just call FunctionsAssemblyResolver.StaticInstance() prior to any IoC resolves. This can also be used for any non-IoC approach as well.

Olindaolinde answered 3/7, 2019 at 15:36 Comment(1)
When I used this version, it generated a StackOverflowException.Tutto
P
2

Add the latest ComponentModel reference into your project using nuget command from Package Manager Console will solve this issue for all type application (Console/Web/Azure).

Install-Package System.ComponentModel.Annotations -Version 4.5.0

Since ComponentModel has not a release of 4.2.0.0 that's why try to install the latest on. Reference: -

Neget Gallery

Preciousprecipice answered 24/1, 2019 at 7:46 Comment(0)
L
1

I had the same problem and what I ended up doing was to downgrade the Microsoft.EntityFrameworkCore package to version 2.0.3 which has a dependency on System.ComponentModel.Annotations 4.4.0 which is the package that the Microsoft.NET.Sdk.Functions 1.0.14 requires. If you have an explicit dependency on System.ComponentModel.Annotations 4.5.0 or greater you need to downgrade that to 4.4.0 as well.

Lundeen answered 6/7, 2018 at 8:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.