2010-04-07 7 views
2

J'ai une question sur la façon dont le framework .NET (2.0) résout les assemblages dépendants..NET substituer des assemblages dépendants sans recompilation?

Nous sommes actuellement impliqués dans une réécriture d'une grande application ASP.NET et de divers exécutables satellites. Il y a aussi quelques problèmes persistants avec nos classes de base que nous avons développé une nouvelle API à résoudre. Jusqu'à présent, il s'agit d'une mise à jour normale, quoique de grande envergure.

Notre heirarchy est:

  1. ASP.NET (ASPX)
  2. logique métier (DLL)
  3. classes de base (DLL)

donc ASP.NET ne jette pas un ajustement, certaines des DLL (en particulier les classes de fondation) ont une couche de redirection qui contient les anciens espaces de noms/fonctions et les transmet à la nouvelle API. Lorsque nous avons remplacé les DLL, ASP.NET les a bien récupérées (probablement parce qu'elles ont déclenché une recompilation).

Les applications précompilées ne le sont pas, même si les mêmes espaces de noms et classes se trouvent dans les deux ensembles de DLL. Même lorsque le fichier est renommé, il se plaint que l'attribut assemblyname soit différent (ce qui doit être nécessairement). Je sais que vous pouvez rediriger vers differnet versions du même assemblage, mais est-il possible de diriger vers un ensemble complètement différent? Les alternatives sont de recompiler les applications (ne veulent pas vraiment parce que les applications elles-mêmes n'ont pas changé) ou recompiler l'ancienne DLL de fondation avec des bouts se référant à la nouvelle DLL de fondation (la nouvelle DLL fictive est le fouillis du système de fichiers).

Répondre

2

Vous souhaitez déplacer les types vers un nouvel assemblage? Vous pouvez le faire avec [TypeForwardedTo(..)].

Si vous avez à l'origine (AssemblyA):

namespace SomeNamespace { 
    public class SomeType {} 
} 

Vous pouvez plutôt déplacer ce type dans AssemblyB et un AssemblyA pratiquement vide qui fait référence AssemblyB et contient simplement:

[assembly: TypeForwardedTo(typeof(SomeNamespace.SomeType))] 

Alors quoi que ce soit essayer de charger SomeNamespace.SomeType de AssemblyAeffectivement obtient le type de AssemblyB.

La plupart du runtime respecte cet attribut ... tout sauf les extensions WCF. Ce qui m'a mordu ;-P Oh, et ce n'est pas fan de types imbriqués ...

+0

J'espérais sortir sans avoir à surmonter la crise, soit l'application d'origine ou les anciennes bibliothèques de l'API. Alors que TypeForwarder est un concept intéressant, il ne fonctionnera pas dans ce cas. RK1.DLL a RK1.API.FUNCTION(). RK2.DLL a RK2.API.Function() et RK1.API1.FUNCTION() qui renvoie vers RK2.API2.Function(). À cause de cela, RK1.DLL et RK2.DLL ne peuvent pas être appelés par la même application et je suppose que le compilateur serait barf si j'essayais de transférer un type à ce qu'il pense être lui-même. Je voulais juste un moyen de supprimer RK2.DLL, de renommer RK1.DLL en RK1.notaDLL et de faire fonctionner l'application. –

+0

J'étais juste surpris que le framework ait supporté le fait de forcer une application à rediriger par version à l'exécution mais pas moyen (que j'ai trouvé) de transférer vers une autre assembly sans recompiler quelque part. –

+0

@RK - tir aveugle dans l'obscurité; avez-vous essayé 'AppDomain.CurrentDomain.AssemblyResolve'? Si elle ne parvient pas à trouver le premier assemblage, vous pouvez le gérer et renvoyer le nouvel assemblage (via 'Assembly.Load (newName)' ... –

0
//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() 
    } 
    } 
} 

Je veux RKAPPLET.EXE, compilé avec RKMFC.DLL, pour trouver RKNET.DLL (qui a une copie de tout dans RKMFC.DLL et un peu) sans recompiler RKAPPLET.EXE (pour pointer vers lui) ou RKMFC.DLL (pour rediriger les types).

Questions connexes