I have a scenario like this:
I'm using interceptor to catch calls to a class that is inside assembly (let's call it Feature) that is referenced by main project. Assembly Feature is installed by NuGet (it's not public but our internal one) and has reference to another assembly (let's call it Core). Main project is referencing assembly Core as well. Core contains class definition that is used as an argument type of one of the intercepted methods.
It all works fine as long as Main project and Feature are referencing the same version of Core library. Problem arises when this versions are different and intercepted method uses types from Core as a method arguments.
In this situation, an exception is thrown that states A strongly-named assembly is required.:
[FileLoadException: Could not load file or assembly 'Core, Version=0.2.2.30, Culture=neutral, PublicKeyToken=null' or one of its dependencies. A strongly-named assembly is required. (Exception from HRESULT: 0x80131044)]
Castle.Proxies.Invocations.IBasketService_Update.InvokeMethodOnTarget() +0
Castle.DynamicProxy.AbstractInvocation.Proceed() +116
Project.Basket.BasketServiceUpdatedInterceptor.Intercept(IInvocation invocation) in c:\(...)\Basket\BasketServiceUpdatedInterceptor.cs:20
Castle.DynamicProxy.AbstractInvocation.Proceed() +604
Castle.Proxies.IBasketServiceProxy.Update(ProductId productId, UInt16 quantity) +210 (...)
Where version of Core 0.2.2.30 is a version that assembly Feature is expecting, main project is using for example version 0.2.2.31. Castle DynamicProxy is not able to find Core with version 0.2.2.30 and that's right because this exact assembly is not deployed to bin folder.
Please note that different versions of Core are a situation perfectly normal in our scenario. Feature assembly is expecting version higher than specified - not exact version.
I'm not sure whether DynamicProxy should be less rigid in it's assembly expectations are I do have to accept this limitation. I've written simple proxy class to overcome this problem so it does not block me anymore yet it blocks us from using DynamicProxy in our solutions.
The problem is caused by the fact that DP was generated against a signed assembly and then an unsigned version of the assembly is being used.
The solution is either to ensure that you use signed assembly in both cases, or to force DynamicProxy to only generate unsigned assembly.
Related
On some machines, executing a razor template via RazorTemplates works OK.
On others, I receive the following message:
TemplateCompilationException
error CS0012: The type 'System.Attribute' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
Info:
This is within a WPF application running on .NET 4.7.
The assembly has a reference to System.Runtime.4.3.0\lib\net462\System.Runtime.dll (v4.1.1.0)
However at runtime, this assembly does not show up in the 'Modules' list.
It seems the Attribute object exists in both System.Runtime and mscorlib.
Looks like this is an underlying issue somewhere between win10 and the RazorTemplates library.
In the end i switched from RazorTemplates to RazorEngine: https://github.com/Antaris/RazorEngine
And there is a page here that explains how to fix the problem via a Resolver:
https://github.com/Antaris/RazorEngine/issues/416
System.Runtime is part of the .Net Framework and is installed in the GAC during framework installation.
This could happen for two possible reasons:
It's not on the machine.
It's the wrong version.
For the machines this fails on check what version of the .Net runtime they have and/or inspect the GAC for this file and version.
Missing the framework, install it. :-)
If machines have a version but it's not the expected version do either:
Install the correct framework version
Use a binding redirect in your config file
I recently took a legacy WCF project with Entity Framework 4 and upgraded it to EF6 and .NET 4.0. I took the legacy Silverlight client project and upgraded as well. Problems started to arise when I added a new service reference to the upgraded WCF service. The code generated in the service reference has conflicts and will not compile.
My initial problem is that both Microsoft.Data.Services.Client and System.Data.Services.Client are part of the references…
CS0433 The type 'EntitySetAttribute' exists in both
'Microsoft.Data.Services.Client, Version=5.6.4.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35' and 'System.Data.Services.Client,
Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
This surprises me even more when I look at the generated code, References.cs, that fails. The usage is fully qualified.
[global::System.Data.Services.Common.EntitySetAttribute("myTable")]. Apparently both assemblies use the exact same namespace.
If I remove Microsoft.Data.Services.Client I get:
Error CS1061 'myEntities4' does not contain a definition for
'DefaultResolveType' and no extension method 'DefaultResolveType'
accepting a first argument of type 'myEntities' could be found (are
you missing a using directive or an assembly reference?)
If I remove System.Data.Services.Client I get:
Could not load file or assembly 'System.Data.Services.Client,
Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or
one of its dependencies. The system cannot find the file specified.
This error is found in the XAML of a UserControl that uses a RadDataServiceDataSource.DataServiceContext.
I have spent quite a few hours trying several different paths including:
Getting older versions of Microsoft.Data.Services.Client from NuGet.
Using only one of the references, as mentioned above.
Changing the references in the WCF service before adding the Service Reference in the client.
Attempting advanced options when adding the Service Reference
Reuse all type from assemblies.
Reuse types in specified referenced assmeblies.
I have read the following posts, but they did not help:
Microsoft.Data.Services.Client.dll vs System.Data.Services.Client.dll
WCF error: Need to exclude all but one of the following types. Only matching types can be valid references
Project does not build after updating a service reference
I'm now considering building a new WCF and Web project to work around these issues. This should be an lengthy undertaking as well, and hopefully not a red herring.
Is this an artifact of upgrading from older versions of Silverlight, WCF, Entity Framework, or .NET in general? Please help me if you know what this is, or you have seen this before. A complete rewrite of the project to another platform is not an option unfortunately.
you can use this code :
EFContext.Configuration.ProxyCreationEnabled = false;
EFContext.Configuration.LazyLoading = false;
When running unit tests, calling any method in my portable runtime library DLL that references the "System.Reflection.TypeExtensions" generates a FileNotFound exception, searching for "System.Reflection.TypeExtensions". The error does not occur when the same code is executed in a Windows 10 Universal app.
The project is a C# portable runtime library, configured to support .net Framework 4.6 and Windows Universal 10.0. The Test project is configured to use .net Framework 4.6.
Whenever I attempt to call a method that uses the System.Reflection.BindingFlags type, I get the following exception. The exception occurs as the call starts (presumably while jit-ing the function).
Test method Sfx.Test.SignalExpressionTest.TestAddExpressions threw exception:
System.IO.FileNotFoundException: Could not load file or assembly 'System.Reflection.TypeExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.=== Pre-bind state information ===
LOG: DisplayName = System.Reflection.TypeExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
(Fully-specified)
Adding those packages is the right thing to do. Here is why you see this behavior:
BindingFlags is currently [1] exposed in System.Reflection.TypeExtensions.
When you compile a .NET Core class library, the compiler records the type reference as System.Reflection.TypeExtensions!System.Reflection.BindingFlags.
When you consume the class library from a .NET Framework application, you need to add a reference to System.Reflection.TypeExtensions otherwise the compiler cannot resolve the type. The same is true for a unit testing project which has to deploy all the code in order to run.
At runtime, the CLR will resolve the type, find a type forward that points to mscorlib!System.Reflection.BindingFlags and happily run your code.
As a general rule of thumb: .NET Core is designed to deploy the framework in an app-local fashion, in other words, when your application is deployed to a folder, the closure of all your dependencies need to be deployed too. Although unit test projects are conceptually class libraries, the same applies because they are executed like applications.
Of course, we don't expect folks to manually tweak the references and hunt down dependencies. What you currently see are pre-release bits where not all pieces in our tooling experiences do the right thing.
Two questions from my side:
Which unit testing framework do you use? I assume it's MSTest (Microsoft.VisualStudio.TestTools.UnitTesting), as opposed to xUnit or NUnit?
Which runner are you using? I assume it's the built-in Visual Studio Test Explorer (as opposed to ReSharper or TestDriven.NET)?
[1] I say currently because based on customer feedback we decided to move it back into System.Reflection, together with the APIs that take BindingFlags.
add reference to nuget packages:
System.Reflection
System.Reflection.Extensions
System.Reflection.Primitives
This question already has answers here:
Is it possible to replace a reference to a strongly-named assembly with a "weak" reference?
(3 answers)
Closed 4 years ago.
I am developing a class library (MyClassLibrary).
I depend on a third party class library (ThirdPartyClassLibrary).
I need to use the same version of ThirdPartyClassLibrary as my users. e.g., if I set a static value in ThirdPartyClassLibrary the user needs to see that change.
Users of my class may be depending on any one of 4 different versions of ThirdPartyClassLibrary.
ThirdPartyClassLibrary is large, I do not want to distribute it with my software.
I have reflected on all 4 versions of ThirdPartyClassLibrary and validated that the things I will be doing with them are compatible across all versions (interfaces are the same, methods signatures are the same, etc.).
I need calls into ThirdPartyClassLibrary to be performant! I can't reflect on everything every time I need to call something.
MyClassLibrary will be loaded at runtime, so I can't expect users to mess with assembly binding redirects or other develop-time settings (or any settings at all, my users are resistant to doing anything).
I would like to benefit from compile-time checking of my code, so ideally no reflection at all.
How can I write MyClassLibrary such that when it is loaded into the process everything works correctly with whichever version of ThirdPartyClassLibrary the user has loaded?
One workaround would be to use the AppDomain.AssemblyResolve event at runtime. This fires whenever the resolution of an assembly fails. You can use this to load a different version of an assembly to that which the CLR is trying to load.
I've added a very simple demo on GitHub here:
https://github.com/danmalcolm/AssemblyResolutionDemo
This is set up as follows:
The main application App.exe directly references assembly ThirdPartyLibrary.dll version 2.0.0.0.
It also references MyLibrary, which references an older version of ThirdPartyLibrary version 1.0.0.0.
The AppDomain.AssemblyResolve event is used to redirect to the version used by the application when version 1.0.0.0 fails to load
AssemblyResolve is handled as follows:
public static void Initialise()
{
AppDomain.CurrentDomain.AssemblyResolve += ResolveThirdPartyLibrary;
}
private static Assembly ResolveThirdPartyLibrary(object sender, ResolveEventArgs args)
{
// Check that CLR is loading the version of ThirdPartyLibrary referenced by MyLibrary
if (args.Name.Equals("ThirdPartyLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=fbcbfac3e44fefed"))
{
try
{
// Load from application's base directory. Alternative logic might be needed if you need to
// load from GAC etc. However, note that calling certain overloads of Assembly.Load will result
// in the AssemblyResolve event from firing recursively - see recommendations in
// http://msdn.microsoft.com/en-us/library/ff527268.aspx for further info
var assembly = Assembly.LoadFrom("ThirdPartyLibrary.dll");
return assembly;
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
}
return null;
}
We need to bind to the event before ThirdPartyLibrary is loaded, hence the explicit Initialise method.
Note also that the event only fires when the resolution of an assembly fails. If the version of ThirdPartyLibrary referenced by MyClassLibrary (1.0.0.0) were available in the GAC, then it would be loaded successfully and AssemblyResolve wouldn't fire. There would then be 2 different versions in use.
I'm demonstrating here that this mechanism could be used, I'm not saying it's a good idea. There are several things you'd need to take into account based on the environment in which your app is running and how it is set-up / installed / maintained etc.
No, you can't build MyClassLibrary with a reference to ThirdPartyClassLibrary in a way that says "just use whatever version of ThirdPartyClassLibrary.dll is available at runtime".
When you build your library, the version number of any referenced assemblies are included in the assembly manifest. Running the ILDASM tool against your assembly would show something like this:
...
.assembly extern ThirdPartyClassLibrary
{
...
.ver 1:0:0:0
}
...
Both the name and version of ThirdPartyClassLibrary are specified. At runtime, the CLR will attempt to load ThirdPartyClassLibrary.dll when it first runs instructions in MyClassLibrary.dll that reference it. It will look specifically for version 1.0.0.0 of ThirdPartyClassLibrary.dll (and will also require a matching public key if it's a strong-named assembly).
Here's a quick overview of how the CLR locates and binds to assemblies at runtime (full details at http://msdn.microsoft.com/en-us/library/yx7xezcf(v=vs.110).aspx):
Step 1 - Determine the correct assembly version by examining configuration files - we'll return to this below, but for now, if you don't tell it otherwise, the CLR will attempt to load the exact version specified in the referencing assembly, so it will be looking for version 1.0.0.0.
Step 2 - Check whether the assembly name has been bound to before and, if so, uses the previously loaded assembly. Note that "assembly name" in this context includes the name and version, public key token etc, not just the name of the dll file.
Step 3 - Check the Global Assembly Cache GAC (strong-named assemblies only)
Step 4 - Locate the assembly through codebases or probing - essentially the CLR looks in different places to try to find (the specific version of) AssemblyB.dll somewhere. An error will occur if it can't find the specific version. It won't automatically fall back to an earlier or later version.
Unfortunately, this means that things won't "just work" and support what you describe above. If an application that references MyClassLibrary itself references a later version (2.0.0.0) of ThirdPartyClassLibrary, some bad things could happen when resolving MyClassLibrary's reference to ThirdPartyClassLibrary:
The CLR can't find version 1.0.0.0 of AssemblyB used by Assembly A and an error occurs
Version 1.0.0.0 happens to be installed in the GAC and is loaded successfully. While the code in the application is using ThirdPartyClassLibrary version 2.0.0.0, your library is using ThirdPartyClassLibrary version 1.0.0.0.
One thing that you can do is configure the application using your library so that the CLR will unify references to different versions of ThirdPartyClassLibrary.dll to a single version. This brings us back to step 1 of the assembly binding process outlined above - we essentially change the version of ThirdPartyClassLibrary that the CLR is looking for.
Binding redirects (http://msdn.microsoft.com/en-us/library/twy1dw1e.aspx) are designed to channel references to different versions of an assembly to a single version. These are usually defined within an application's configuration file (Web.config, MyApp.exe.config), but can also be defined globally at machine level (machine.config).
Here's an example of a binding redirect that redirects all earlier versions of ThirdPartyClassLibrary.dll to version 2.0.0.0:
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="AssemblyB" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Note that this can be automatically handled by Visual Studio 2013, which detects cases where different versions of an assembly are referenced and adds the binding redirects for you. There's also an Add-BindingRedirect command available in the NuGet Package Manager Console.
Binding redirects are a possible solution and could be a pragmatic choice in some scenarios. However, they could also confuse users of your library. If practical, you should consider distributing different versions of your library, built against the different versions of the third party library.
A little bit of background: I recently recompiled the ServiceStack library from its source code (https://github.com/ServiceStack/ServiceStack). I also recompiled the ServiceStack.Text project, after completing some bug fixes. I copied the ServiceStack.Text dll file into the "lib" folder of the ServiceStack project (it is there because the ServiceStack solution does not include the serializers in Text).
Now I am getting TypeLoadExceptions, as follows:
System.TypeLoadException: Method 'get_StatusCode' in type
'ServiceStack.ServiceInterface.Testing.MockHttpResponse' from assembly
'ServiceStack.ServiceInterface, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null' does not have an implementation. at
System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly
assembly, ObjectHandleOnStack retTypes) at
System.Reflection.RuntimeAssembly.GetExportedTypes() at ----my code
from here...----
I'm not sure what the issue could be. I suspected it could be a circular DLL reference issue (DLL Hell) because ServiceStack.OrmLite is referenced (which also references back to other solutions in this project); however, after removing all references to ServiceStack projects, I still have not solved the problem.
This post seems to have some ideas, but I have not had any luck following through with those: TypeLoadException says 'no implementation', but it is implemented
You're using dirty dlls for the different versions of ServiceStack's components which should all be kept in sync.
In the assembly of each major ServiceStack component dll is marked the version number, this matches up with the version that's deployed on NuGet, e.g. the latest version of ServiceStack is v3.9.38, you would want to ensure that you're using at least v3.9.38 of all the other libraries.
The core ServiceStack dependency matrix looks like:
ServiceStack.Text
+
> ServiceStack.Interfaces
> ServiceStack.Common
+
> ServiceStack.Redis
> ServiceStack.OrmLite
+
> ServiceStack
+
> ServiceStack.ServiceInterface
If you're using v3.9.38 of ServiceStack.dll, you want to make sure that all sub components above ServiceStack is at least at v3.9.38.