C# 将参数传递到从C中的dll检索的T4运行时模板#
我有一个DLL,它有一个T4运行时模板和一个通过方法返回该模板实例的类(模板名为Query.tt,它生成了类Query.cs): 来自dll的模板:C# 将参数传递到从C中的dll检索的T4运行时模板#,c#,dll,t4,C#,Dll,T4,我有一个DLL,它有一个T4运行时模板和一个通过方法返回该模板实例的类(模板名为Query.tt,它生成了类Query.cs): 来自dll的模板: <#@ template language="C#" #> <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ import namespace="System.Text" #> <#@ imp
<#@ template language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ template debug="true" #>
<#@ parameter name="TestObj" type="TemplateDLL.Class2" #>
Hellow <#= this.TestObj.s #>!
Hellow <#= this.TestObj.x #>!
namespace TemplateDLL
{
public class Class1
{
public Query getQueryTemplate()
{
return new Query();
}
}
}
我正在使用反射将此dll加载到另一个项目中:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
namespace TestDynTemplate2
{
class Program
{
static void Main(string[] args)
{
var DLL = Assembly.LoadFile(@"D:\somedllpath\TemplateDLL.dll");
dynamic c = Activator.CreateInstance(DLL.GetType("TemplateDLL.Class1"));
var templateInstance = c.getQueryTemplate();
TemplateDLL.Class2 c2 = new TemplateDLL.Class2();
c2.x = 3;
c2.s = "cdfafdafa";
templateInstance.Session = new Dictionary<string, object>();
templateInstance.Session.Add("TestObj", c2);
templateInstance.Initialize();
var generatedCode = templateInstance.TransformText();
Console.WriteLine(generatedCode);
}
}
}
在对象抛出System.InvalidCastException时在模板中使用该对象之前,一切都正常工作:[a]TemplateDLL.Class2无法强制转换为[B]TemplateDLL.Class2。它告诉我A型和B型的起源是不一样的
我们如何才能做到这一点?我不熟悉c#和T4。在c#(以及在.NET中)相同的定义并不意味着相同的类
程序集A中声明的Class2
和程序集B中声明的Class2
是完全不同的类(它们同时共享相同的命名空间和类名),因为类由其全名和程序集(还包括处理器体系结构和公钥,请参阅以获取更多详细信息)定义
您必须在声明该类型或从一种类型复制到另一种类型的位置共享程序集(例如,通过反射)。大概是这样的:
var instanceInBType = instanceInB.GetType();
foreach (var fieldInA in instanceFromA.GetType().GetFields())
{
var fieldInB = instanceInBType.GetField(field.Name);
var valueInA = fieldInA.GetValue(instanceFromA);
fieldInB.SetValue(instanceInB, valueInA);
}
实际上,您必须接受一个泛型的对象
参数(instanceFromA
),创建一个局部变量instanceInB
,并将字段从a复制到B。当然,共享类型定义肯定更好…在C#(通常在.NET中)中,相同的定义并不意味着相同的类
程序集A中声明的Class2
和程序集B中声明的Class2
是完全不同的类(它们同时共享相同的命名空间和类名),因为类由其全名和程序集(还包括处理器体系结构和公钥,请参阅以获取更多详细信息)定义
您必须在声明该类型或从一种类型复制到另一种类型的位置共享程序集(例如,通过反射)。大概是这样的:
var instanceInBType = instanceInB.GetType();
foreach (var fieldInA in instanceFromA.GetType().GetFields())
{
var fieldInB = instanceInBType.GetField(field.Name);
var valueInA = fieldInA.GetValue(instanceFromA);
fieldInB.SetValue(instanceInB, valueInA);
}
实际上,您必须接受一个泛型对象
参数(instancefrom
),创建一个局部变量instanceInB
,并将字段从a复制到B。当然,共享类型定义肯定更好