I'm trying to allow a Desktop Bridge application to register for WNS notifications from an Azure Notification Hub, but when I actually use the UWP APIs it throws
`System.IO.FileNotFoundException: 'Could not load file or assembly 'System.Runtime.WindowsRuntime, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.'
with an inner exception of
FileNotFoundException: Could not load file or assembly 'System.Runtime.WindowsRuntime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.
I set up my solution following the Visual Studio packaging instructions. My package project has a target version of Fall Creators Update, minimum version of Anniversary Update, and I associated it with a Windows Dev Center project for WNS support. All my .NET Framework projects are targeting v4.6.2. If I don't call any UWP APIs, the packaged application runs perfectly.
All the WNS code is in a single Class Library project, and that project is referenced by my desktop application (which is added to the package project's Applications). The class library has references for all six files in Microsoft's tutorial, with Copy Local = False for the three .winmd files:
the three DLLs from C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5
C:\Program Files (x86)\Windows Kits\10\UnionMetadata\Facade\Windows.winmd
C:\Program Files (x86)\Windows Kits\10\References\10.0.16299.0\Windows.Foundation.UniversalApiContract\5.0.0.0\Windows.Foundation.UniversalApiContract.winmd
C:\Program Files (x86)\Windows Kits\10\References\10.0.16299.0\Windows.Foundation.FoundationContract\3.0.0.0\Windows.Foundation.FoundationContract.winmd
The actual push notification function is inside an async method:
public namespace WnsClassLibrary
{
public class WnsChannelService
{
private PushNotificationChannel _channel;
public async Task CreateChannel()
{
_channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
}
}
}
When the desktop application starts it tries to call CreateChannel() as an unawaited async method, and that's when the exception is thrown - as far as I can tell, it doesn't even actually make it inside the method.
Does anyone know why this happens or how I fix it? I tried setting the packaging project's minimum version to Fall Creators Update as suggested in UWP application: Could not load file or assembly 'System.Runtime.WindowsRuntime, Version=4.0.14.0, but I still get the same exception.
It looks like the problem might not actually be in Desktop Bridge or the UWP API references, but just a misconfigured assembly binding redirect.
While trying to get the exception to show up in a smaller solution, I found
<configuration>
<!--[unrelated configuration data...]-->
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Runtime.WindowsRuntime" publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.10.0" newVersion="4.0.10.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
in the app.config files for both the desktop app and the WNS class library. Deleting that <runtime> element makes everything run fine, and copy/pasting it into my reproduction project makes the System.IO.FileNotFoundException start showing up.
I can't figure out what added that assembly binding redirect or make it happen again, but the desktop app was originally .Net 4.5 and took plenty of experimentation to migrate to .Net 4.6.2, update all the Nuget packages, and implement Desktop Bridge. My best guess is that something may have triggered a Nuget automatic configurator along the way?
In my windows class library (consumed by a MVC website) I have installed the NugetPackage Microsoft.SqlServer.Types (Spatial).
Now, using ado.net I am trying to read the value by doing:
protected SqlGeography MapSqlGeography(DbDataReader reader, string key)
{
return reader[key] is DBNull ? null : (SqlGeography)reader[key];
}
If I add a brake point in this line and in the visual studio watch window I type: "reader[key]", I can see the correct Point(XXXX,XXX) of type: "object {Microsoft.SqlServer.Types.SqlGeography}"
But, as soon as I try to make the cast I have the following error:
(SqlGeography)reader[key] The type 'Microsoft.SqlServer.Types.SqlGeography' exists in both
'Microsoft.SqlServer.Types.dll' and
'Microsoft.SqlServer.Types.dll'
Main strange fact is that the dlls are exactly the same...
As far as I know I only have one "source" for this namespace/class name, it should not be duplicated....
My "usings" are:
using Microsoft.SqlServer.Types;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.SqlClient;
using System.Threading.Tasks;
Any ideas on how to solve this? Thanks.
Update #1
I uninstalled the NugetPackage `Microsoft.SqlServer.Types (Spatial)' and instead tried the one called: 'Microsoft.SqlServer.Types (Unofficial)' and even after cleaning all the previous folders/files and also cleaning up the "bin/obj", I continue to have the exact same exception....
I simply do now see the cause of this now.... any ideas would be really appreciated.
Update #2
Just tried to use extern alias destination;
return reader[key] is DBNull
? null
: (destination.Microsoft.SqlServer.Types.SqlGeography)reader[key];
And have the exception:
Cannot cast 'reader[key]' (which has an actual type of 'Microsoft.SqlServer.Types.SqlGeography')
to
'Microsoft.SqlServer.Types.SqlGeography'
Microsoft.SqlServer.Types.SqlGeography
I encountered this error today because a referenced library included a different version of Microsoft.SqlServer.Types from Nuget than the locally installed one.
You can install a matching version using Nuget to resolve the issue, or you may be able to use binding redirects if that is not an option.
For example:
Install-Package Microsoft.SqlServer.Types -Version 10.50.1600.1
Check your specific versions by looking at package.json for your dependencies, or perhaps you can check the DLL properties directly.
The runtime uses the following steps to resolve an assembly reference:
Determines the correct assembly version by examining applicable configuration files, including the application configuration file, publisher policy file, and machine configuration file. If the configuration file is located on a remote machine, the runtime must locate and download the application configuration file first.
Checks whether the assembly name has been bound to before and, if so, uses the previously loaded assembly.
Checks the global assembly cache. If the assembly is found there, the runtime uses this assembly.
Probes for the assembly using the following steps:
If configuration and publisher policy do not affect the original reference and if the bind request was created using the Assembly.LoadFrom method, the runtime checks for location hints.
If a codebase is found in the configuration files, the runtime checks only this location. If this probe fails, the runtime determines that the binding request failed and no other probing occurs.
Probes for the assembly using the heuristics described in the probing section. If the assembly is not found after probing, the runtime requests the Windows Installer to provide the assembly. This acts as an install-on-demand feature.
Note There is no version checking for assemblies without strong names, nor does the runtime check in the global assembly cache for assemblies without strong names.
Now, check to see if you have multiple assemblies referenced (as Damien_The_Unbeliever said in the comment) or you do not have specific version set for that assembly.
Also you can try the Assembly Binding Log Viewer (Fuslogvw) to see exactly what gets loaded and what are the search paths.
Try using this in your web.config file:
<dependentAssembly>
<assemblyIdentity name="Microsoft.SqlServer.Types" publicKeyToken="89845dcd8080cc91" culture="neutral" />
<bindingRedirect oldVersion="10.0.0.0-11.0.0.0" newVersion="14.0.0.0" />
</dependentAssembly>
I am developing PowerShell binary module. It uses Json.NET and other libraries.
I am getting this exception "Could not load file or assembly 'Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified.'
On hard drive I have an updated version of it (version 7.0.2)
Problems like that are easily solved in console, web or desktop application, with app.config or "web.config" via lines like this
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
How can I do something similar for PowerShell binary module?
After coming across this issue myself while developing a PowerShell module that uses multiple 3rd party libraries (Google API, Dropbox, Graph, etc) I found the following solution was the simplest:
public static Assembly CurrentDomain_BindingRedirect(object sender, ResolveEventArgs args)
{
var name = new AssemblyName(args.Name);
switch (name.Name)
{
case "Microsoft.Graph.Core":
return typeof(Microsoft.Graph.IBaseClient).Assembly;
case "Newtonsoft.Json":
return typeof(Newtonsoft.Json.JsonSerializer).Assembly;
case "System.Net.Http.Primitives":
return Assembly.LoadFrom("System.Net.Http.Primitives.dll");
default:
return null;
}
}
Note in the method, I've got two possible ways to reference the assembly, but both of them do the same thing, they force the current version of that assembly to be used. (Regardless if it is loaded via class reference or dll file load)
To use this in any cmd-let add the following event handler in the BeginProcessing() method of the PSCmdLet.
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_BindingRedirect;
The closest i've found so far is:
Add the problem assembly to the manifest's RequiredAssemblies - this causes it to be loaded into the AppDomain when the module is loaded.
Use the code from this SO answer - it adds an AssemblyResolve handler to the current AppDomain, which searches for assemblies already loaded and returns ones which match by strong name and PublicKeyToken
After using the module, you have to do the following to avoid stack overflows when exiting: [System.AppDomain]::CurrentDomain.remove_AssemblyResolve($OnAssemblyResolve)
Steps 1 and 2 could both be encapsulated in the module, but step 3 can't, which means this isn't suitable as a general solution - the caller has to know about it. So I'm still searching for a better way.
You need to add a manifest to your module.
The simplest way is:
New-ModuleManifest -RequiredAssemblies:"path\to\newtonSoft.dll"
Then modify the manifest file manually for any other tweaks.
If the manifest doesn't solve the problem, you may need to pull out the nuclear hammer and set the binding redirects for ALL of powershell as mentioned in Powershell - Assembly binding redirect NOT found in application configuration file
For binary modules, there are a few keys that need to be populated in the manifest file for successful import/functionality:
RootModule = <'binaryModule.dll'>
RequiredAssemblies = <'binaryModule.dll'>
CmdletstoExport = '*' <--no need to restrict anything here, as
only the public functions you've developed in the assembly
will be exported to the user.
Those are the only keys you need to populate for the module to 'work' -- though I highly suggest combing through the .psd1 file generated byNew-ModuleManifest -path MyNewModule.psd1 to what other metadata values would help enrich the functionality of your module.
Also, ensure the names of the directory structure, .psd1 file, and assembly are all consistent.
SampleModule\
SampleModule\SamleModule.dll
SampleModule\SampleModule.psd1
...that should do it.
I've got a very weird bug on our test machine. The error is:
System.TypeLoadException: Method 'SetShort' in type 'DummyItem' from assembly 'ActiveViewers (...)' does not have an implementation.
I just can't understand why. SetShort is there in the DummyItem class, and I've even recompiled a version with writes to the event log just to make sure that it's not a deployment/versioning issue. The weird thing is that the calling code doesn't even call the SetShort method.
NOTE - If this answer doesn't help you, please take the time to scroll down through the other answers that people have added since.
Short answer
This can happen if you add a method to an interface in one assembly, and then to an implementing class in another assembly, but you rebuild the implementing assembly without referencing the new version of the interface assembly.
In this case, DummyItem implements an interface from another assembly. The SetShort method was recently added to both the interface and the DummyItem - but the assembly containing DummyItem was rebuilt referencing the previous version of the interface assembly. So the SetShort method is effectively there, but without the magic sauce linking it to the equivalent method in the interface.
Long answer
If you want to try reproducing this, try the following:
Create a class library project: InterfaceDef, add just one class, and build:
public interface IInterface
{
string GetString(string key);
//short GetShort(string key);
}
Create a second class library project: Implementation (with separate solution), copy InterfaceDef.dll into project directory and add as file reference, add just one class, and build:
public class ImplementingClass : IInterface
{
#region IInterface Members
public string GetString(string key)
{
return "hello world";
}
//public short GetShort(string key)
//{
// return 1;
//}
#endregion
}
Create a third, console project: ClientCode, copy the two dlls into the project directory, add file references, and add the following code into the Main method:
IInterface test = new ImplementingClass();
string s = test.GetString("dummykey");
Console.WriteLine(s);
Console.ReadKey();
Run the code once, the console says "hello world"
Uncomment the code in the two dll projects and rebuild - copy the two dlls back into the ClientCode project, rebuild and try running again. TypeLoadException occurs when trying to instantiate the ImplementingClass.
In addition to what the asker's own answer already stated, it may be worth noting the following. The reason this happens is because it is possible for a class to have a method with the same signature as an interface method without implementing that method. The following code illustrates that:
public interface IFoo
{
void DoFoo();
}
public class Foo : IFoo
{
public void DoFoo() { Console.WriteLine("This is _not_ the interface method."); }
void IFoo.DoFoo() { Console.WriteLine("This _is_ the interface method."); }
}
Foo foo = new Foo();
foo.DoFoo(); // This calls the non-interface method
IFoo foo2 = foo;
foo2.DoFoo(); // This calls the interface method
I got this when my application didn't have a reference to another assembly defining a class that the method in the error message used. Running PEVerify gave more helpful error: "The system cannot find the file specified."
I came across the same message and here is what we have found:
We use third party dlls in our project. After a new release of those was out we changed our project to point to the new set of dlls and compiled successfully.
The exception was thrown when I tried to instatiate one of the their interfaced classes during run time.
We made sure that all the other references were up to date, but still no luck.
We needed a while to spot (using the Object Browser) that the return type of the method in the error message was a completely new type from a new, unreferenced assembly.
We added a reference to the assembly and the error disappeared.
The error message was quite misleading, but pointed more or less to the right direction (right method, wrong message).
The exception ocurred even though we did not use the method in question.
Which leads me to the question: If this exception is thrown in any case, why does the compiler not pick it up?
I received this error in the following scenario.
Both Assemblies A and B referenced System.Web.Mvc Version 3.0.0.0
Assembly A referenced Assembly B and had classes which implemented interfaces from Assembly B with methods which returned classes from System.Web.Mvc.
Assembly A upgraded to System.Web.Mvc Version 4.0.0.0
Assembly C ran the code below (FertPin.Classes.Contact was contained in Assembly A):
var target = Assembly.GetAssembly(typeof(FertPin.Classes.Contact));
The fix for me was upgrading the System.Web.Mvc reference in Assembly B to 4.0.0.0. Seems obvious now!
Thanks to the original poster!
The other time you can get this error is if you have an incorrect version of a signed assembly. It's not the normal symptom for this cause, but here was the scenario where I got it
an asp.net project contains assembly A and assembly B, B is strongly named
assembly A uses Activator.CreateInstance to load assembly C (i.e. there is no reference to C which is built separately)
C was built referencing an older version of assembly B than is currently present
hope that helps someone - it took me ages to figure this out.
I had this error too, it was caused by an Any CPU exe referencing Any CPU assemblies that in turn referenced an x86 assembly.
The exception complained about a method on a class in MyApp.Implementations (Any CPU), which derived MyApp.Interfaces (Any CPU), but in fuslogvw.exe I found a hidden 'attempt to load program with an incorrect format' exception from MyApp.CommonTypes (x86) which is used by both.
I keep coming back to this...
Many of the answers here do a great job of explaining what the problem is but not how to fix it.
The solution to this is to manually delete the bin files in your projects published directory. It will clean up all the references and force the project to use the latest DLLs.
I don't suggest using the publish tools Delete function because this tends to throw off IIS.
I encountered this error in a context where I was using Autofac and a lot of dynamic assembly loading.
While performing an Autofac resolution operation, the runtime would fail to load one of the assemblies. The error message complained that Method 'MyMethod' in type 'MyType' from assembly 'ImplementationAssembly' does not have an implementation. The symptoms occurred when running on a Windows Server 2012 R2 VM, but did not occur on Windows 10 or Windows Server 2016 VMs.
ImplementationAssembly referenced System.Collections.Immutable 1.1.37, and contained implementations of a IMyInterface<T1,T2> interface, which was defined in a separate DefinitionAssembly. DefinitionAssembly referenced System.Collections.Immutable 1.1.36.
The methods from IMyInterface<T1,T2> which were "not implemented" had parameters of type IImmutableDictionary<TKey, TRow>, which is defined in System.Collections.Immutable.
The actual copy of System.Collections.Immutable found in the program directory was version 1.1.37. On my Windows Server 2012 R2 VM, the GAC contained a copy of System.Collections.Immutable 1.1.36. On Windows 10 and Windows Server 2016, the GAC contained a copy of System.Collections.Immutable 1.1.37. The loading error only occurred when the GAC contained the older version of the DLL.
So, the root cause of the assembly load failure was the mismatching references to System.Collections.Immutable. The interface definition and implementation had identical-looking method signatures, but actually depended on different versions of System.Collections.Immutable, which meant that the runtime did not consider the implementation class to match the interface definition.
Adding the following binding redirect to my application config file fixed the issue:
<dependentAssembly>
<assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.1.37.0" newVersion="1.1.37.0" />
</dependentAssembly>
I have yet another esoteric solution to this error message. I upgraded my target framework from .Net 4.0 to 4.6, and my unit test project was giving me the "System.TypeLoadException...does not have an implementation" error when I tried to build. It also gave a second error message about the same supposedly non-implemented method that said "The 'BuildShadowTask' task failed unexpectedly." None of the advice here seemed to help, so I searched for "BuildShadowTask", and found a post on MSDN which led me to use a text editor to delete these lines from the unit test project's csproj file.
<ItemGroup>
<Shadow Include="Test References\MyProject.accessor" />
</ItemGroup>
After that, both errors went away and the project built.
I got this with a "diamond" shaped project dependency:
Project A uses Project B and Project D
Project B uses Project D
I recompiled project A but not Project B, which allowed Project B to "inject" the old version of the Project D dll
I encountered this when I renamed a project (and the assembly name), which was depended upon by an ASP.NET project. Types in the web project implemented interfaces in the dependent assembly. Despite executing Clean Solution from the Build menu, the assembly with the previous name remained in the bin folder, and when my web project executed
var types = AppDomain.CurrentDomain.
GetAssemblies().
ToList().
SelectMany( s => s.GetTypes() /* exception thrown in this call */ )
;
the above exception was thrown, complaining that interface methods in the implementing web types were not actually implemented. Manually deleting the assembly in the web project's bin folder resolved the problem.
I also got this error when I had previously enabled Code Coverage during unit testing for one of the assemblies. For some reason Visual Studio "buffered" the old version of this particular DLL even though I had updated it to implement a new version of the interface. Disabling Code Coverage got rid of the error.
This error can also be caused if an assembly is loaded using Assembly.LoadFrom(String) and is referencing an assembly that was already loaded using Assembly.Load(Byte[]).
For instance you have embedded the main application's referenced assemblies as resources but your app loads plug-ins from a specific folder.
Instead of using LoadFrom you should use Load. The following code will do the job:
private static Assembly LoadAssemblyFromFile( String filePath )
{
using( Stream stream = File.OpenRead( filePath ) )
{
if( !ReferenceEquals( stream, null ) )
{
Byte[] assemblyData = new Byte[stream.Length];
stream.Read( assemblyData, 0, assemblyData.Length );
return Assembly.Load( assemblyData );
}
}
return null;
}
FWIW, I got this when there was a config file that redirected to a non-existent version of a referenced assembly. Fusion logs for the win!
I got this error because I had a class in an assembly 'C' which was on version 4.5 of the framework, implementing an interface in assembly 'A' which was on version 4.5.1 of the framework and serving as the base class to assembly 'B' which was also on version 4.5.1 of the framework. The system threw the exception while trying to load assembly 'B'. Additionally, I had installed some nuget packages targeting .net 4.5.1 on all three assemblies. For some reason, even though the nuget references were not showing in assembly 'B', it was building successfully.
It turned out that the real issue was that the assemblies were referencing different versions of a nuget package that contained the interface and the interface signature had changed between versions.
Another explanation for this type of problem involving managed C++.
If you try to stub an interface defined in an assembly created using managed C++ that has a special signature you will get the exception when the stub is created.
This is true for Rhino Mocks and probably any mocking framework that uses System.Reflection.Emit.
public interface class IFoo {
void F(long bar);
};
public ref class Foo : public IFoo {
public:
virtual void F(long bar) { ... }
};
The interface definition gets the following signature:
void F(System.Int32 modopt(IsLong) bar)
Note that the C++ type long maps to System.Int32 (or simply int in C#). It is the somewhat obscure modopt that is causing the problem as stated by Ayende Rahien on the Rhino Mocks mailing list .
I just upgraded a solution from MVC3 to MVC5, and started receiving the same exception from my Unit test project.
Checked all the references looking for old files, eventualy discovered I needed to do some bindingRedirects for Mvc, in my unit test project.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
In my case it helped to reset the WinForms Toolbox.
I got the exception when opening a Form in the designer; however, compiling and running the code was possible and the code behaved as expected. The exception occurred in a local UserControl implementing an interface from one of my referenced libraries. The error emerged after this library was updated.
This UserControl was listed in the WinForms Toolbox. Probably Visual Studio kept a reference on an outdated version of the library or was caching an outdated version somewhere.
Here is how I recovered from this situation:
Right click on the WinForms Toolbox and click on Reset Toolbox in the context menu. (This removes custom items from the Toolbox).
In my case the Toolbox items were restored to their default state; however, the Pointer-arrow was missing in the Toolbox.
Close Visual Studio.
In my case Visual Studio terminated with a violation exception and aborted.
Restart Visual Studio.
Now everything is running smoothly.
In my case I had previously referenced a mylib project in a sibling folder outside of the repo - let's call that v1.0.
|-- myrepo
| |-- consoleApp
| |-- submodules
| |-- mylib (submoduled v2.0)
|-- mylib (stale v1.0)
Later I did it properly and used it via a git submodule - lets call that v2.0.
One project consoleApp however wasn't updated properly. It was still referencing the old v1.0 project outside of my git project.
Confusingly, even though the *.csproj was plainly wrong and pointing to v1.0, the Visual Studio IDE showed the path as the v2.0 project!
F12 to inspect the interface and class went to the v2.0 version too.
The assembly placed into the bin folder by the compiler was the v1.0 version, hence the headache.
That fact that the IDE was lying to me made it extra hard to realise the error.
Solution: Deleted project references from ConsoleApp and readded them.
General Tip: Recompile all assemblies from scratch (where possible, can't for nuget packages of course) and check datetime stamps in bin\debug folder. Any old dated assemblies are your problem.
I faced almost same issue. I was scratching my head what is causing this error.
I cross checked, all the methods were implemented.
On Googling I got this link among other. Based on #Paul McLink comment, This two steps resolved the issue.
Restart Visual Studio
Clean, Build (Rebuild)
and the error gone.
Restart VS Plugin
Thanks Paul :)
Hope this helps someone who come across this error :)
I also ran into this problem while running my unittests. The application ran fine and with no errors.
The cause of the problem in my case was that I had turned off the building of the test projects.
Reenabling the building of my testprojects solved the issues.
I saw this in Visual Studio Pro 2008 when two projects built assemblies with the same name, one a class lib SDF.dll, and one that referenced the lib with assembly name sdf.exe.
When I changed the name of the referencing assembly, the exception went away
This simply means that the implementation project is out of date in my cases. The DLL containing the interface was rebuilt but the implementation dll was stale.
Here's my take on this error.
Added an extern method, but my paste was faulty. The DllImportAttribute got put on a commented out line.
/// <returns>(removed for brevity lol)</returns>[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsWindowVisible(IntPtr hWnd);
Ensuring the attribute was actually included in source fixed the issue.
I got this in a WCF service due to having an x86 build type selected, causing the bins to live under bin\x86 instead of bin. Selecting Any CPU caused the recompiled DLLs to go to the correct locations (I wont go into detail as to how this happened in the first place).
I got this issue when I tried to implement plugin assembly loading in dot net 5 using custom AssemblyLoadContext (without AppDomain creation) and shared type (interface which you need to use to call plugin methods without reflection). Nothing from this thread helped me. Here is what I did to solve this issue:
To allow debugging of plugin loading without a problems - setup project output path to host app bin folder. You will debug the same assembly you got after plugin project build. This is, probably, temporary change (just for debug).
To fix TypeLoadException you need to load all 'contract assembly' referenced assemblies as shared assemblies (except runtime assemblies). Check loader context implementation (loading sharedAssemblies in constructor):
public class PluginAssemblyLoadContext : AssemblyLoadContext
{
private AssemblyDependencyResolver _resolver;
private IDictionary<string, Assembly> _loadedAssemblies;
private IDictionary<string, Assembly> _sharedAssemblies;
private AssemblyLoadContext DefaultAlc;
private string _path;
public PluginAssemblyLoadContext(string path, bool isCollectible, params Type[] sharedTypes)
: this(path, isCollectible, sharedTypes.Select(t => t.Assembly).ToArray())
{
}
public PluginAssemblyLoadContext(string path, bool isCollectible, params Assembly[] sharedAssemblies)
: base(isCollectible: isCollectible)
{
_path = path;
DefaultAlc = GetLoadContext(Assembly.GetExecutingAssembly()) ?? Default;
var fileInfo = new FileInfo(_path);
if (fileInfo.Exists)
{
_resolver = new AssemblyDependencyResolver(_path);
_sharedAssemblies = new Dictionary<string, Assembly>(StringComparer.OrdinalIgnoreCase);
foreach (var a in sharedAssemblies.Distinct())
{
LoadReferencedAssemblies(a);
}
_loadedAssemblies = new Dictionary<string, Assembly>();
var assembly = LoadFromAssemblyPath(fileInfo.FullName);
_loadedAssemblies.Add(fileInfo.FullName, assembly);
}
else
{
throw new FileNotFoundException($"File does not exist: {_path}");
}
}
public bool LoadReferencedAssemblies(Assembly assembly)
{
if (assembly == null)
{
throw new ArgumentNullException(nameof(assembly));
}
if (string.IsNullOrEmpty(assembly.Location))
{
throw new NotSupportedException($"Assembly location is empty string or null: {assembly.FullName}");
}
var alc = GetLoadContext(assembly);
if (alc == this)
{
throw new InvalidOperationException($"Circular assembly loader dependency detected");
}
if (!_sharedAssemblies.ContainsKey(assembly.Location))
{
_sharedAssemblies.Add(assembly.Location, assembly);
foreach (var an in assembly.GetReferencedAssemblies())
{
var ra = alc.LoadFromAssemblyName(an);
LoadReferencedAssemblies(ra);
}
return true;
}
else
{
return false;
}
}
public IEnumerable<Type> GetCommandTypes<T>()
{
var cmdType = typeof(T);
return _loadedAssemblies.Values.SelectMany(a => a.GetTypes()).Where(t => cmdType.IsAssignableFrom(t));
}
public IEnumerable<T> CreateCommands<T>(Assembly assembly)
{
foreach (var cmdType in GetCommandTypes<T>())
{
yield return (T)Activator.CreateInstance(cmdType);
}
}
protected override Assembly Load(AssemblyName assemblyName)
{
var path = _resolver.ResolveAssemblyToPath(assemblyName);
if (path != null)
{
if (_sharedAssemblies.ContainsKey(path))
{
return _sharedAssemblies[path];
}
if (_loadedAssemblies.ContainsKey(path))
{
return _loadedAssemblies[path];
}
return LoadFromAssemblyPath(path);
}
return DefaultAlc.LoadFromAssemblyName(assemblyName);
}
}
Usage:
var loader = new PluginAssemblyLoadContext(fullPath, false, typeof(IPluginCommand));
loader.CreateCommands<IPluginCommand>()...
I had the same problem. I figured out that my assembly, which is loaded by the main program, had some references with "Copy Local" set to true. These local copies of references were looking for other references in the same folder, which did not exist because the "Copy Local" of other references was set to false. After the deletion of the "accidentally" copied references the error was gone because the main program was set to look for correct locations of references. Apparently the local copies of the references screwed up the sequence of calling because these local copies were used instead of the original ones present in the main program.
The take home message is that this error appears due to the missing link to load the required assembly.
In my case, I was attempting to use TypeBuilder to create a type. TypeBuilder.CreateType threw this exception. I eventually realized that I needed to add MethodAttributes.Virtual to the attributes when calling TypeBuilder.DefineMethod for a method that helps implements an interface. This is because without this flag, the method does not implement the interface, but rather a new method with the same signature instead (even without specifying MethodAttributes.NewSlot).
As an addendum: this can also occur if you update a nuget package that was used to generate a fakes assembly. Say you install V1.0 of a nuget package and create a fakes assembly "fakeLibrary.1.0.0.0.Fakes". Next, you update to the newest version of the nuget package, say v1.1 which added a new method to an interface. The Fakes library is still looking for v1.0 of the library. Simply remove the fake assembly and regenerate it. If that was the issue, this will probably fix it.