Свой класс Template и позднее связывание

Тема в разделе ".NET", создана пользователем Basilevs, 4 апр 2007.

Статус темы:
Закрыта.
  1. Basilevs

    Basilevs Гость

    Необходимо создать класс. В котором определён метод, который на строку("%<Date.Time.Now >%") возвращает строку с текущим временем. Вместо Date.Time.Now может быть какое угодно значение. Thread.CurrentThread.Id и так далее. Так же необходимо предусмотреть использование цикла for внутри <%%> и вывода в выходную сроку соответствующего значения столько раз, сколько пройдёт цикл. ТАк же как параметры в функцию можно посылать используемые сборки. Подскажите, пожалуйста идеи реализации!
     
  2. Basilevs

    Basilevs Гость

    Задания такие дают:)
     
  3. Pasha

    Pasha Гость

    Идея реализации:
    генерируешь на диске временный файл вида
    Код (Text):
    public class MegaRenderer
    {
    public object Render(Stream writer)
    {
    // сюда вставляешь код из <% ... %>
    }
    }
    Компилируешь его в сборку с помощью csc.exe (добавляя в параметры используемые сборки). Потом подгружаешь и вызываешь Render. Можно еще синтаксис разнообразить, ввести <%=, <%#...
     
  4. Basilevs

    Basilevs Гость

    А с помощью рефлекциитипов и MethodBuilder-а это можно как-то реализовать?
     
  5. NikSoft

    NikSoft Гость

    Да можно. Модифицируй нижеследующий пример для своих целей.

    Код (Text):
    using System;
    using System.Threading;
    using System.Reflection;
    using System.Reflection.Emit;


    class DemoMethodBuilder {

    public static void AddMethodDynamically (ref TypeBuilder myTypeBld,
    string mthdName,
    Type[] mthdParams,
    Type returnType,
    string mthdAction)
    {

    MethodBuilder myMthdBld = myTypeBld.DefineMethod(
    mthdName,
    MethodAttributes.Public |
    MethodAttributes.Static,
    returnType,
    mthdParams);   

    ILGenerator ILout = myMthdBld.GetILGenerator();

    int numParams = mthdParams.Length;

    for (byte x=0; x<numParams; x++) {
    ILout.Emit(OpCodes.Ldarg_S, x);
    }

    if (numParams > 1) {
    for (int y=0; y<(numParams-1); y++) {
    switch (mthdAction) {
    case "A": ILout.Emit(OpCodes.Add);
    break;
    case "M": ILout.Emit(OpCodes.Mul);
    break;
    default: ILout.Emit(OpCodes.Add);
    break;
    }
    }
    }
    ILout.Emit(OpCodes.Ret);



    }

    public static void Main()
    {

    AppDomain myDomain = Thread.GetDomain();
    AssemblyName asmName = new AssemblyName();
    asmName.Name = "DynamicAssembly1";

    AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
    asmName,
    AssemblyBuilderAccess.RunAndSave);

    ModuleBuilder myModule = myAsmBuilder.DefineDynamicModule("DynamicModule1",
    "MyDynamicAsm.dll");

    TypeBuilder myTypeBld = myModule.DefineType("MyDynamicType",
    TypeAttributes.Public);  

    // Get info from the user to build the method dynamically.

    Console.WriteLine("Let's build a simple method dynamically!");
    Console.WriteLine("Please enter a few numbers, separated by spaces.");
    string inputNums = Console.ReadLine();
    Console.Write("Do you want to [A]dd or [M]ultiply these numbers? ");
    string myMthdAction = Console.ReadLine();
    Console.Write("Lastly, what do you want to name your new dynamic method? ");
    string myMthdName = Console.ReadLine();

    // Process inputNums into an array and create a corresponding Type array

    int index = 0;
    string[] inputNumsList = inputNums.Split();

    Type[] myMthdParams = new Type[inputNumsList.Length];
    object[] inputValsList = new object[inputNumsList.Length];


    foreach (string inputNum in inputNumsList) {
    inputValsList[index] = (object)Convert.ToInt32(inputNum);
    myMthdParams[index] = typeof(int);
    index++;
    }

    // Now, call the method building method with the parameters, passing the
    // TypeBuilder by reference.

    AddMethodDynamically(ref myTypeBld,
    myMthdName,
    myMthdParams,
    typeof(int),   
    myMthdAction);

    Type myType = myTypeBld.CreateType();

    Console.WriteLine("---");
    Console.WriteLine("The result of {0} the inputted values is: {1}",
    ((myMthdAction == "A") ? "adding" : "multiplying"),
    myType.InvokeMember(myMthdName,
    BindingFlags.InvokeMethod | BindingFlags.Public |
    BindingFlags.Static,
    null,
    null,
    inputValsList));
    Console.WriteLine("---");

    // Let's take a look at the method we created.

    // If you are interested in seeing the MSIL generated dynamically for the method
    // your program generated, change to the directory where you ran the compiled
    // code sample and type "ildasm MyDynamicAsm.dll" at the prompt. When the list
    // of manifest contents appears, click on "MyDynamicType" and then on the name of
    // of the method you provided during execution.

    myAsmBuilder.Save("MyDynamicAsm.dll");

    MethodInfo myMthdInfo = myType.GetMethod(myMthdName);
    Console.WriteLine("Your Dynamic Method: {0};", myMthdInfo.ToString());

    }

    }
    Также вот тебе две ссылки. Может быть ты найдешь их интересными.

    http://www.codeproject.com/dotnet/Creating_Dynamic_Types.asp
    http://www.codeproject.com/useritems/Creat...amic_Types2.asp
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей