.NET substitute dependent assemblies without recompiling?
I have a question about how the .NET framework (2.0) resolves dependent assemblies.
We're currently involved in a bit of a rewrite of a large ASP.NET application and various satellite executables. There are also some nagging problems with our foundation classes that we developed a new API to solve. So far this is a normal, albeit wide-reaching, update.
Our heirarchy is:
- ASP.NET (aspx)
- business logic (DLLs)
- foundation classes (DLLs)
So ASP.NET doesn't throw a fit, some of the DLLs (specifically the foundation classes) have a redirection layer that contains the old namespaces/functions and forwards them to the new API. When we replaced the DLLs, ASP.NET picked them up fine (probably because it triggered a recompile).
Precompiled applications don't though, even though the same namespaces and classes are in both sets of DLLs. Even when the file is renamed, it complains about the assemblyname attribute being different (which it has to be by necessity). I know you can redirect to differnet versions of the same assembly, but is 开发者_开发知识库there any way to direct to a completely different assembly?
The alternatives are to recompile the applications (don't really want to because the applications themselves haven't changed) or recompile the old foundation DLL with stubs refering to the new foundation DLL (the new dummy DLL is file system clutter).
You want to move the types to a new assembly? You can do that with [TypeForwardedTo(..)]
.
If you originally have (AssemblyA
):
namespace SomeNamespace {
public class SomeType {}
}
You can instead move that type into AssemblyB
, and have a virtually empty AssemblyA
which references AssemblyB
and simply contains:
[assembly: TypeForwardedTo(typeof(SomeNamespace.SomeType))]
Then anything trying to load SomeNamespace.SomeType
from AssemblyA
actually gets the type from AssemblyB
.
Most of the runtime respects this attribute... everything except WCF extensions. Which bit me ;-p Oh, and it isn't a fan of nested types...
//File: RKAPPLET.EXE
namespace RKAPPLET
{
using RKMFC;
public static class Program
{
public static void Main ()
{
RKMFC.API.DoSomething();
}
}
}
//File: RKMFC.DLL
namespace RKMFC
{
public static class API
{
public static void DoSomething ()
{
System.Windows.Forms.MessageBox.Show("MFC!")
}
}
}
//File: RKNET.DLL
namespace RKNET
{
public static class API
{
public static void DoSomethingElse ()
{
System.Windows.Forms.MessageBox.Show("NET!")
}
}
}
namespace RKMFC
{
public static class API
{
public static void DoSomething ()
{
RKNET.API.DoSomethingElse()
}
}
}
I want RKAPPLET.EXE, compiled with RKMFC.DLL, to find RKNET.DLL (which has a copy of everything in RKMFC.DLL and then some) without recompiling either RKAPPLET.EXE (to point to it) or RKMFC.DLL (to redirect types).
Did you try adding <assemblyBinding>
setting to config file ?
http://msdn.microsoft.com/en-us/library/twy1dw1e.aspx
精彩评论