2010-04-10 10 views
4

J'essaie de créer un assembly dynamiquement dans .Net. Cependant, je n'arrive pas à comprendre comment obtenir la propriété CodeBase pour renvoyer une valeur. Voici un exemple:Impossible d'accéder à CodeBase à partir d'un assembly généré dynamiquement

var assemblyName = new AssemblyName 
         { 
          Name = "Whatever", 
          CodeBase = Directory.GetCurrentDirectory() 
         }; 
var assemblyBuilder = AppDomain.CurrentDomain 
    .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); 
var moduleBuilder = assemblyBuilder.DefineDynamicModule("WhateverModule", "Whatever.dll"); 
var typeBuilder = moduleBuilder.DefineType("WhateverType", TypeAttributes.Public); 
var type = typeBuilder.CreateType(); 
assemblyBuilder.Save("Whatever.dll"); 
var codeBase = type.Assembly.CodeBase; // throws the below exception 

System.NotSupportedException was unhandled 
    Message=The invoked member is not supported in a dynamic assembly. 
    Source=mscorlib 
    StackTrace: 
     at System.Reflection.Emit.InternalAssemblyBuilder.get_CodeBase() 
     at Stupid.Program.Main(String[] args) in C:\Users\Walking Disaster\Documents\Visual Studio 10\Projects\Lingual.Proxy\Stupid\Program.cs:line 25 
     at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
     at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 

Quelqu'un peut-il voir ce que je fais mal?

Explication: J'essaie d'étendre NUnit avec un addin qui génère des méthodes de test lors de l'exécution. Il le fait en prenant un tableau de délégués d'action. Malheureusement, Reflection est cuit assez profondément dans le cadre, j'ai donc dû émettre des classes avec une méthode pour chaque délégué d'action. Cela fonctionne correctement lorsque j'utilise les classes NUnitTestMethod uniquement, mais lorsque j'utilise NUnitTestFixture, il échoue car il essaie de lire la base de code à partir de l'assembly. Je ne voulais pas créer un assemblage physique, mais ce projet a été un compromis après l'autre.

Répondre

2

Je pense que la cause de l'exception est que CodeBase n'a aucun sens sur l'assemblage dynamique. De MSDN:

L'emplacement de l'ensemble tel que spécifié à l'origine

Si vous rechargerez l'ensemble il ne sera pas jeter l'exception:

var assemblyName = new AssemblyName 
         { 
          Name = "Whatever", 
          CodeBase = Directory.GetCurrentDirectory() 
         }; 
var assemblyBuilder = AppDomain.CurrentDomain 
    .DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); 
var moduleBuilder = assemblyBuilder.DefineDynamicModule(
    "WhateverModule", "Whatever.dll"); 
var typeBuilder = 
       moduleBuilder.DefineType("WhateverType", TypeAttributes.Public); 
var type = typeBuilder.CreateType(); 
assemblyBuilder.Save("Whatever.dll"); 

var assembly = Assembly.LoadFrom("Whatever.dll"); 
var codeBase = assembly.CodeBase; // this won't throw exception 
+0

J'avais peur de cela. Je pourrais devoir faire ceci pour être fait, alors creuser plus profondément dans NUnit pour essayer de limiter les dommages que leur dépendance forte à la réflexion provoque. –

1

est-Location de l'Assemblée valide ? Pourriez-vous forker NUnit et l'utiliser à la place étant donné votre référence à être endommagé: P

J'ai passé quelques heures à être soumis à l'histoire de l'extensibilité de NUnit et je ne peux pas m'imaginer l'avoir jamais choisi sur xUnit.net - mais je suppose le décideur de cela sera combien de tests vous avez ...

+1

Je suis avec vous. Je n'arrive pas à croire que NUnit a choisi d'obtenir toutes les métadonnées de test par réflexion. Malheureusement, ceci est pour un projet existant, et nous avons déjà des tests 7K + NUnit. Je sais que xUnit vous permet d'exécuter des tests NUnit, mais il y a un désincitatif à le rapprocher de l'achèvement du projet. Je cherche à transférer mon travail à xUnit, cependant, pour le prochain projet. –

+1

Je suppose que c'est assez improbable, mais avez-vous regardé RunWithNUnitAttribute [qui vous permet d'exécuter des tests NUnit via le runner xunit]. Havent a vu des exemples autour de lui mais vous seriez surpris de voir à quel point les échantillons de xunit sont propres et brefs (téléchargez des échantillons et cherchez NUnitRunnerAcceptanceTests)? (Oui, un tir très long!) –