I try to generate the following code, where G<T> is defined in an
external dll :

public class Test
{
    public static void Check<U>()
    {
        U f = G<U>.F;   >> code to generate!
    }
}

Here is my code, but its fails to execute.

I think that the problem is to be able to define a IGenericContext
with the current MethodDefinition Check<U>, and a specific
TypeReference (in my code, the typeContext  variable). But is it
sufficient to resolve all importation cases ?

assembly1.dll :
public class G<T>
{
    public static T F;
}

Test.exe :
public class Test
{
  public static void Main() {

       // Create the AssemblyDefinition
        AssemblyDefinition a = AssemblyDefinition.CreateAssembly(new
AssemblyNameDefinition("output.dll", new Version()), "TestModule",
ModuleKind.Dll);

        /*
        // Create the G<T> Type
        TypeDefinition GOfT;
        a.MainModule.Types.Add(GOfT =
             new TypeDefinition(null, "G", TypeAttributes.Public |
TypeAttributes.Class, a.MainModule.Import(typeof(object))));
        GenericParameter T = new GenericParameter("T", GOfT);
        GOfT.GenericParameters.Add(T);

        // Create the G<T>.F static Field
        FieldDefinition FinGofT;
        GOfT.Fields.Add(FinGofT = new FieldDefinition("F",
FieldAttributes.Public | FieldAttributes.Static, T));
        */

        AssemblyDefinition aref =
AssemblyDefinition.ReadAssembly("assembly1.dll");

        // Get the G<T> type
        TypeDefinition GOfT;
        GOfT = aref.MainModule.GetType("G`1");

        // Get the G<T>.F static Field
        FieldDefinition FinGofT;
        FinGofT = GOfT.Fields[0];

        // Create the Test Type
        TypeDefinition Test;
        a.MainModule.Types.Add(Test =
             new TypeDefinition(null, "Test", TypeAttributes.Public |
TypeAttributes.Class, a.MainModule.Import(typeof(object))));

        // Create the Test.Check<U> Method
        MethodDefinition CheckOfU;
        Test.Methods.Add(CheckOfU = new MethodDefinition("Check",
MethodAttributes.Public | MethodAttributes.Static,
a.MainModule.Import(typeof(void))));
        GenericParameter U = new GenericParameter("U", CheckOfU);
        CheckOfU.GenericParameters.Add(U);

        // Get the G<U> type reference
        GenericInstanceType GofU = new GenericInstanceType(GOfT);
        GofU.GenericArguments.Add(U);
        TypeReference typeContext = a.MainModule.Import(GofU,
CheckOfU);

        // Get the G<U>.F static Field
        FieldReference fInGofU = new FieldReference("F",
FinGofT.FieldType)
        {
            DeclaringType = GofU
        };

        // Defines the instructions

        CheckOfU.Body.Variables.Add(new VariableDefinition("f",
a.MainModule.Import(typeof(int))));
 
CheckOfU.Body.Instructions.Add(Instruction.Create(OpCodes.Ldsfld,
a.MainModule.Import(fInGofU, CheckOfU))); // this line fails!!!
 
CheckOfU.Body.Instructions.Add(Instruction.Create(OpCodes.Stloc_0));
 
CheckOfU.Body.Instructions.Add(Instruction.Create(OpCodes.Ret));

        a.Write("output.dll");

        // Check the assembly
 
SR.Assembly.LoadFrom("output.dll").GetType("Test").GetMethod("Main",
SR.BindingFlags.Public | SR.BindingFlags.Static).Invoke(null, null);
}
}

I have included the Assembly1.7z file that contains the sample
solution for VS 2008.

Thanks a lot for your help.

Regis

-- 
--
mono-cecil

Reply via email to