Comments (13)
Not sure if this is related, but I had a similar issue when upgrading to Microsoft.NET.Sdk.Functions 3.0.6 with various nuget packages failing with "Unexpected error: Could not load file or assembly" errors.
I was able to resolve them by adding
<_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
as a property in my cproj file.
from functionmonkey.
Could you please expand a little more information to reproduce your issue? Base class for what for the commands or for the command handlers?
Your project that you publish in NuGet refers Microsoft. Extensions.Dependency Injection.Abstractions or FunctionMonkey nuget packages?
from functionmonkey.
Typically each Azure Function would implement IFunctionAppConfiguration
and fill in the Build method with function configurations to make use of FunctionMonkey. In my case, they're mostly Http Route functions with a handful of ServiceBus topic triggers.
Our particular setup is using MediatR along with several service registrations that are common to all the Azure Function projects. Because we have multiple Azure Functions, we created a base class that abstracts the common setup like logging, validation, and pipeline creation.
It looks like this for any given Azure Function:
public class FunctionAppConfiguration : ApiBootstrap
{
...
}
public class ApiBootstrap : IFunctionAppConfiguration
{
public void Build(IFunctionHostBuilder builder)
{
builder.Setup(services =>
{
....
}
}
}
Originally both classes were part of the same solution. Since then, we've moved our core libraries to a NuGet feed. The ApiBootstrap (and several project dependencies and service implementations) are now referenced in the project via NuGet instead of a direct project reference.
After that one change, the FunctionMoneky compiler isn't able to compile the functions. We've traced it down to any external class or interface that's now referenced in a NuGet package. Keep in mind, these classes haven't changed at all; only the way they're referenced in each project has changed.
It appears that the FunctionMonkey target can't compile the code when it tries to find implementations.
For example, we have a class called DatabaseInitializer
that implements an interface IDatabaseInitializer
that run when a function starts up. The interface is shared via one of our NuGet packages. When we compile, we get the following error:
Unexpected error: ReflectionTypeLoadException: Unable to load one or more of the requested types.Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=3.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
Could not find or load a specific file. (0x80131621)Unable to load types: Blueprint.Forms.Api.IDatabaseInitializer Blueprint.Forms.Api.DatabaseInitializer Blueprint.Forms.Api.DatabaseInitializer+<SeedAsync>d__3 Blueprint.Forms.Api.DatabaseInitializer+<SeedData>d__4 Blueprint.Forms.Api.FunctionAppConfiguration+<>c null type
in ReflectionTypeLoadExceptionWith errors: FileLoadException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=3.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
Could not find or load a specific file. (0x80131621) at FunctionMonkey.ConfigurationLocator.Find[TType](Assembly assembly)
in /Users/jamesrandall/code/functionMonkey/library/Source/FunctionMonkey/ConfigurationLocator.cs:line 202 at FunctionMonkey.ConfigurationLocator.Scan[TType](MethodInfo& linkBackInfo, TType& findConfiguration)
in /Users/jamesrandall/code/functionMonkey/library/Source/FunctionMonkey/ConfigurationLocator.cs:line 155 at FunctionMonkey.ConfigurationLocator.Find[TType]()
in /Users/jamesrandall/code/functionMonkey/library/Source/FunctionMonkey/ConfigurationLocator.cs:line 129 at FunctionMonkey.ConfigurationLocator.FindFunctionAppHost(Assembly assembly)
in /Users/jamesrandall/code/functionMonkey/library/Source/FunctionMonkey/ConfigurationLocator.cs:line 18 at FunctionMonkey.Compiler.Core.Compiler.Compile()
in /Users/jamesrandall/code/functionMonkey/library/Source/FunctionMonkey.Compiler.Core/Compiler.cs:line 57 at FunctionMonkey.Compiler.Program.Main(String[] args)
in /Users/jamesrandall/code/functionMonkey/library/Source/FunctionMonkey.Compiler/Program.cs:line 56 | Blueprint.Forms.Api | C:\Users\Tyler\.nuget\packages\functionmonkey.compiler\4.0.56-beta.4\build\netstandard1.0\FunctionMonkey.Compiler.targets
Note that the error says it can't find Blueprint.Forms.Api.IDatabaseInitializer.
When we remove the code that registers the the instance, we get a slightly different, but still failing error:
Unexpected error: ReflectionTypeLoadException: Unable to load one or more of the requested types.Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=3.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
Could not find or load a specific file. (0x80131621)Unable to load types: Blueprint.Forms.Api.FunctionAppConfiguration+<>c null type
in ReflectionTypeLoadExceptionWith errors: FileLoadException: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=3.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'.
Could not find or load a specific file. (0x80131621) at FunctionMonkey.ConfigurationLocator.Find[TType](Assembly assembly)
in /Users/jamesrandall/code/functionMonkey/library/Source/FunctionMonkey/ConfigurationLocator.cs:line 202 at FunctionMonkey.ConfigurationLocator.Scan[TType](MethodInfo& linkBackInfo, TType& findConfiguration)
in /Users/jamesrandall/code/functionMonkey/library/Source/FunctionMonkey/ConfigurationLocator.cs:line 155 at FunctionMonkey.ConfigurationLocator.Find[TType]()
in /Users/jamesrandall/code/functionMonkey/library/Source/FunctionMonkey/ConfigurationLocator.cs:line 129 at FunctionMonkey.ConfigurationLocator.FindFunctionAppHost(Assembly assembly) in /Users/jamesrandall/code/functionMonkey/library/Source/FunctionMonkey/ConfigurationLocator.cs:line 18 at FunctionMonkey.Compiler.Core.Compiler.Compile()
in /Users/jamesrandall/code/functionMonkey/library/Source/FunctionMonkey.Compiler.Core/Compiler.cs:line 57 at FunctionMonkey.Compiler.Program.Main(String[] args)
in /Users/jamesrandall/code/functionMonkey/library/Source/FunctionMonkey.Compiler/Program.cs:line 56 | Blueprint.Forms.Api | C:\Users\Tyler\.nuget\packages\functionmonkey.compiler\4.0.56-beta.4\build\netstandard1.0\FunctionMonkey.Compiler.targets
In this case, the FunctionMonkey compiler still cannot find the type that the FunctionAppConfiguration inherits from.
Again, when all the code is in a single project it works fine. But moving base classes to a NuGet package is enough to cause FunctionMonkey to fail during compilation.
from functionmonkey.
Could you please expand a little more information to reproduce your issue? Base class for what for the commands or for the command handlers?
Your project that you publish in NuGet refers Microsoft. Extensions.Dependency Injection.Abstractions or FunctionMonkey nuget packages?
Yes, one of the NuGet packages references FunctionMonkey as a NuGet project reference
from functionmonkey.
I pulled down the FunctionMonkey source and ran against an empty project with the same error. That's good news; it's not hard to reproduce.
The code fails in FunctionMonkey.Compiler when loading assemblies even though the assembly is there in the correct directory
Specifically, the failure is thrown by Assembly referencedAssembly = context.LoadFromAssemblyPath(path);
when loading Microsoft.Extensions.DependencyInjection.Abstractions
AssemblyLoadContext.Default.Resolving += (context, name) =>
{
string path = Path.Combine(outputBinaryDirectory, $"{name.Name}.dll");
//string path = $"{outputBinaryDirectory}\\{name.Name}.dll";
if (File.Exists(path))
{
Assembly referencedAssembly = context.LoadFromAssemblyPath(path);
return referencedAssembly;
}
return null;
};
from functionmonkey.
Uncovering more as I dig deeper. I found a couple odd behaviors I can't yet explain.
First, the assembly resolving fails outright to load the Microsoft.Extensions.DependencyInjection.Abstractions DLL in the Resolving lambda. I modified it as follows to allow the assembly to load, and so far it seems to work:
AssemblyLoadContext.Default.Resolving += (context, name) =>
{
string path = Path.Combine(outputBinaryDirectory, $"{name.Name}.dll");
//string path = $"{outputBinaryDirectory}\\{name.Name}.dll";
if (File.Exists(path))
{
Assembly referencedAssembly = null;
try
{
referencedAssembly = context.LoadFromAssemblyPath(path);
}
catch
{
return Assembly.LoadFile(path);
}
return referencedAssembly;
}
return null;
};
That modification at least resolves and successfully loads the assembly, but it's not sufficient to get the compilation to work.
What follows after assembly and type loading (i.e. after the call to FindFunctionAppHost) is something I can't yet explain. I'm not at all new to reflection, but this is something I've not encountered before.
Around line 90 in the compiler, the compiler attempts to invoke configuration.Build(builder)
which was working for me when all code was in a single project. Remember, the Build method is in a base class that in the NuGet package's library.
Now, when the Build is invoked, reflection cannot find the method and throws an exception when attempting to call it. The strange thing is that the method is there. To test further, I added a method called "BuildTest" to my Azure function, and then instead of calling configuration.Build(builder)
, I instead used reflection to invoke my new method. In my dummy method, I'm simply calling the base class' Build method with the IFunctionHostBuilder argument.
The temporary function looks like this:
public void BuildTest(IFunctionHostBuilder builder)
{
base.Build(builder);
}
Here's where I'm stumped - I set a breakpoint on the base.Build(...)
line, and when I try to call the base class' Build method, a missing method exception is thrown. It makes no sense to me because the method is clearly there. The code compiles. Intellisense works and see the method and points to the symbols included in the NuGet package. It seems like the process of resolving assembly dependencies isn't loading the base class' DLL as a dependency and is therefore failing to call the base class Build(..) method.
I will keep digging, but this one is a first for me. It may have to do with .Net Core and package management in some way. All the projects are .Net Core 3.1; perhaps there's something about that which prevents the method invocation.
from functionmonkey.
I tested my project with a version of Microsoft.NET.Sdk.Functions greater than 3.0.3 and started getting the same error "Could not load file or assembly"... @TylerBrinks could you please describe which version of Microsoft.NET.Sdk.Functions you are using?
from functionmonkey.
I tested my project with a version of Microsoft.NET.Sdk.Functions greater than 3.0.3 and started getting the same error "Could not load file or assembly"... @TylerBrinks could you please describe which version of Microsoft.NET.Sdk.Functions you are using?
I'm using 3.0.6 but I'll try the 3.0.6 release.
from functionmonkey.
Not sure if this is related, but I had a similar issue when upgrading to Microsoft.NET.Sdk.Functions 3.0.6 with various nuget packages failing with "Unexpected error: Could not load file or assembly" errors.
I was able to resolve them by adding
<_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
as a property in my cproj file.
I made that change and something changed. I'm able to access my base class' methods now from the derived class. I still can't invoke them from the FunctionMonkey compiler, but it's a step closer.
from functionmonkey.
I double checked my original solution (as opposed to my scratch project in the FunctionMonkey solution) and I was already on 3.0.6 and happened to have the <_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
already in place.
One fact that may have some relevance, when the assemblies are loaded mine are all .NETCoreApp,v=3.1 where the Microsoft dependency injection assembly is .NETStandard,v2.0
from functionmonkey.
@TylerBrinks Try to downgrade Microsoft.NET.Sdk.Functions to 3.0.3 version.
from functionmonkey.
@TylerBrinks Try to downgrade Microsoft.NET.Sdk.Functions to 3.0.3 version.
Just did that in both my actual project and a scratch project in the FunctionMonkey code with same error. I'm not sure if much will work if the compiler can't get past the inability to load the Microsoft.Extensions.DependencyInjection.Abstractions library.
from functionmonkey.
We are using FunctionMonkey built with Azure Pipelines in production. I believe I can remember these problems. The root cause was that parts of the required libraries are loaded from the SDK and in an Azure Pipeline build this works somehow different from a local build.
-
It is important you install the correct .Net Core SDK on the build machine. Use the task: "Use .NET Core", choose "SDK" and enter the exact version. We use 3.1.201.
-
Add to all your .csproj files:
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
Our full YAML pipeline file as reference (some things overwritten with xxxxxxxxxxxxxxxx):
pool:
name: Azure Pipelines
demands:
- msbuild
- visualstudio
- vstest
variables:
BuildPlatform: 'any cpu'
BuildConfiguration: 'debug'
steps:
-
task: UseDotNet@2
displayName: 'Use .Net Core sdk 3.1.201'
inputs:
version: 3.1.201 -
task: NuGetToolInstaller@0
displayName: 'Use NuGet 4.x'
inputs:
versionSpec: 4.x -
task: NuGetCommand@2
displayName: 'NuGet restore'
inputs:
restoreSolution: 'xxxxxxxxxxxxxxxx.sln'
vstsFeed: 'xxxxxxxxxxxxxxxx' -
task: VSBuild@1
displayName: 'Build solution'
inputs:
solution: 'xxxxxxxxxxxxxxxx.sln'
msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\"'
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)' -
task: VSTest@2
displayName: 'Test assemblies'
inputs:
testAssemblyVer2: |
*test.dll
!*TestAdapter.dll
!\obj**
!**.Test.Base.dll
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
diagnosticsEnabled: True -
task: PublishSymbols@2
displayName: 'Publish symbols path'
inputs:
PublishSymbols: false -
task: PublishBuildArtifacts@1
displayName: 'Publish Artifact: xxxxxxxxxxxxxxxx'
inputs:
ArtifactName: xxxxxxxxxxxxxxxx
Hope this helps somehow and good luck,
Markus
from functionmonkey.
Related Issues (20)
- CamelCaseJsonSerializer does not work for ExpandoObject
- HttpResponseHandler not used for BadParameterResponse in http.csharp.handlebars HOT 1
- Receive and add CancellationToken to DI to enable for graceful shutdowns HOT 1
- Problems with StorageQueue in 4.0.56-beta4 HOT 2
- Event Grid Triggers
- Unable to upload a file
- HowTo BeforeServiceProviderBuild HOT 1
- Solution Structure
- Http Trigger: AuthorizationLevel.Anonymous runs ClaimsPrincipalAuthorization but it should be ignored HOT 3
- How to access Cookie (and QueryString) collection ?
- Future of Function Monkey HOT 10
- Compiler Build Error with Entity Framework Core HOT 4
- Add Validators via Assembly search not working HOT 2
- Primitives / Arrays in HTTP body
- Need a way to access full HttpContext HOT 2
- FunctionMonkey.Compiler can't be built
- Accessing request headers
- Azure App Configuration in Configuration.
- CosmosDB lease container appears inoperable
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from functionmonkey.