-
Notifications
You must be signed in to change notification settings - Fork 485
Description
TL;DR: I am either misunderstanding how ModuleScope.SaveAssembly works, or DynamicProxy — when it produces proxies for types in weak-named assemblies — puts generated proxy types in a weak-named module and proxy method invocation types in a strong-named module, resulting in failure or incomplete output by ModuleScope.SaveAssembly.
The generated assemblies mentioned below can be found in CastleDynProxy2_strong_and_weak.zip.
Saving with ModuleScope.SaveAssembly(strongNamed: false)
Suppose I'm trying to save the dynamic assembly generated by DynamicProxy as follows:
using Castle.DynamicProxy;
public interface IFoo
{
void Method();
}
public abstract class Bar
{
public abstract void Method();
}
class Program
{
public static void Main()
{
var proxyGenerator = new ProxyGenerator(new PersistentProxyBuilder());
var foo = proxyGenerator.CreateInterfaceProxyWithoutTarget<IFoo>();
var bar = proxyGenerator.CreateClassProxy<Bar>();
proxyGenerator.ProxyBuilder.ModuleScope.SaveAssembly(strongNamed: false);
}
}Note that I am not strong-naming the assembly containing above code—if I did, then everything would work as expected.
This generates an assembly CastleDynProxy2, which appears to have two problems:
-
It is missing types
Castle.Proxies.Invocations.IFoo_MethodandCastle.Proxies.Invocations.Bar_Method. PEVerify is a bit cryptic about it, but seems to tell me the same thing:[IL]: Error: [C:\...\CastleDynProxy2.dll : Castle.Proxies.IFooProxy::Method] [HRESULT 0x80070002] - The system cannot find the file specified. [IL]: Error: [C:\...\CastleDynProxy2.dll : Castle.Proxies.BarProxy::Method [HRESULT 0x80070002] - The system cannot find the file specified. 2 Error(s) Verifying CastleDynProxy2.dll -
There is an assembly reference to a strong-named
DynamicProxyGenAssembly2, which is confusing, because the generated assembly already has the exact same name (except for being weak-named).
If I try to run code that references and uses the CastleDynProxy2.dll as produced above, I will get a FileNotFoundException (perhaps due to the second issue above):
class Program
{
static void Main()
{
var bar = new BarProxy();
}
}Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
at Program.Main()
Saving with ModuleScope.SaveAssembly(strongNamed: true)
When I change the last line of the original program (at the top) to:
proxyGenerator.ProxyBuilder.ModuleScope.SaveAssembly(strongNamed: true);
// ^^^^and inspect the generated assembly CastleDynProxy2.dll (which is now strong-named), I see this:
- The assembly has the invocation types
Castle.Proxies.Invocations.IFoo_MethodandCastle.Proxies.Invocations.Bar_Method, but it is missing the proxy typesCastle.Proxies.IFooProxyandCastle.Proxies.BarProxy.
Saving with ModuleScope.SaveAssembly()
If I try to save the assembly without specifying strongNamed: false, nor strongNamed: true, I get an exception right away:
Unhandled Exception: System.InvalidOperationException: Both a strong-named and a weak-named assembly have been generated.
at Castle.DynamicProxy.ModuleScope.SaveAssembly()
at Program.Main() in ...\Program.cs:line 20
Possible conclusions
-
I am making a beginner mistake (hinted at by the last exception shown just above). What I don't understand in this case is, how would I let DynamicProxy save a correct, weak-named dynamic assembly referencing types
IFoo,Barfrom my own weak-named assembly?SaveAssembly(strongNamed: false)doesn't seem to do the trick. -
When generating proxies for types in weak-named assemblies, DynamicProxy puts the proxy types in a weak-named assembly and the invocation types in a strong-named assembly. Therefore it will only be able to save either of those at a time, but fails to save both. This results in incomplete output assembly either way.
What is going wrong here?