Essayer de localiser le constructeur manuellement peut être difficile, mais vous devriez toujours avoir celui que vous avez généré plus tôt? Avez-vous essayé de le passer celui-là? Je vais essayer de faire un exemple ...
var assemblyName = new AssemblyName("tmp");
var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
var module = assembly.DefineDynamicModule("tmp");
var foo = module.DefineType("Foo");
var bar = module.DefineType("Bar");
var barOnFoo = foo.DefineField("bar", bar, FieldAttributes.Private);
var fooOnBar = bar.DefineField("foo", foo, FieldAttributes.Private);
var barCtor = bar.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[] { foo });
var il = barCtor.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Stfld, fooOnBar);
il.Emit(OpCodes.Ret);
var fooCtor = foo.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, Type.EmptyTypes);
il = fooCtor.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Newobj, barCtor);
il.Emit(OpCodes.Stfld, barOnFoo);
il.Emit(OpCodes.Ret);
// create the actual types and test object creation
Type fooType = foo.CreateType(), barType = bar.CreateType();
object obj = Activator.CreateInstance(fooType);
Je pourrais ajouter du code supplémentaire pour vérifier le résultat, mais il est plus facile de regarder obj
dans le débogueur, et vous pouvez voir les champs, etc.
pour les cas plus complexes - ne pas oublier que vous n'avez pas besoin d'écrire le corps d'une méthode (iL) pour l'utiliser ... vous pouvez écrire toutes les signatures premières (DefineMethod
, DefineConstructor
, etc.), puis écrire tous les corps après, permettant le code entièrement cyclique.
Il s'avère que l'erreur s'est située ailleurs. La méthode que bar appelait foo, était protégée, donc la vie était bonne quand la barre était imbriquée dans foo, quand je l'ai déplacée, elle n'était pas capable d'appeler cette méthode. Je l'ai changé pour le public et la vie est de nouveau bon. Il s'avère que SRE et 2am ne se mélangent pas. Merci quand même. –