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

  • Автор темы Basilevs
  • Дата начала
Статус
Закрыто для дальнейших ответов.
B

Basilevs

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

Pasha

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

Basilevs

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

NikSoft

#5
А с помощью рефлекциитипов и MethodBuilder-а можно как-то реализовать?
Да можно. Модифицируй нижеследующий пример для своих целей.

Код:
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
 
Статус
Закрыто для дальнейших ответов.