gpt4 book ai didi

c# - 通过对同一程序集的反射生成代码

转载 作者:太空狗 更新时间:2023-10-30 00:25:46 24 4
gpt4 key购买 nike

我已经开始涉足 T4 并且一开始相处得很好,但是后来遇到了一个实际上非常明显并且可能无法解决的问题,但也许有一种方法我只是缺乏经验才能知道或看到。

给定以下类:

public class T4Test : CodeActivity
{
protected override void Execute(CodeActivityContext context)
{
}

[Input("InX")]
public InArgument<string> InX { get; set; }

[Output("OutX")]
public OutArgument<string> OutX { get; set; }
}

我想要这个作为输出:

public class ActivityWrapper
{
private readonly T4Test _activity;
private readonly ActivityContext _context;

public ActivityWrapper(T4Test activity, ActivityContext context)
{
this._activity = activity;
this._context = context;
}

public string InX
{
get { return this._activity.InX.Get(this._context); }
}

public string OutX
{
get { return this._activity.OutX.Get(this._context); }
set { this._activity.OutX.Set(this._context, value); }
}
}

我已经弄清楚了我需要的反射内容,并且我知道 T4 代码应该是什么样子,但是有一个问题:我需要在与 T4Test 类相同的项目中使用它。但是,要加载程序集并对其进行反射,需要对其进行编译——当然,如果我打算修改同一个程序集的代码,这就有点困难了。 (我想 NCrunch 并没有简化事情。)

下面是我希望仍然可以解决这个问题的事情:

  • 项目在没有生成的类的情况下进行编译。这是因为该类将实现由 IoC 容器自动注册/解析的接口(interface)。它也是不可测试的,因为 ActivityContext 不能被模拟。
  • 因此,它不必一直存在或正确。在实际交付 DLL 之前,我只需要能够说“现在生成这个”。
  • 出于同样的原因,我也不关心 T4 模板是否实际位于项目中 - 只要生成的文件最终出现在项目中(尽管不需要另一个模板项目和构建 PostBuild 事件来复制一个.cs 文件)。
  • 准确地说,甚至不需要是T4。如果有任何其他可行的方法,我也很乐意使用它。

有什么办法可以实现吗? (这还不够清楚吗?)

最佳答案

我想提出一个反射(reflect)生成的程序集的替代方案,因为只有当项目成功构建并生成正确的输出时转换 T4 才有效,前提是程序集没有过时。

如果您使用主机特定的 T4 模板,您可以通过 EnvDTE 接口(interface)访问 Visual Studio 自动化模型。使用它,您可以遍历当前加载的 Visual Studio 解决方案的代码模型,而无需先构建它。

看看我对这个 SO 问题的回答:Design Time Reflection .借助 tangible 的模板库中的免费模板,您可以在设计时轻松地“反射(reflect)”您现有的类,并检测使用所需属性装饰的属性:

<#
var project = VisualStudioHelper.CurrentProject;

// get all class items from the code model
var allClasses = VisualStudioHelper.GetAllCodeElementsOfType(project.CodeModel.CodeElements, EnvDTE.vsCMElement.vsCMElementClass, false);

// iterate all classes
foreach(EnvDTE.CodeClass codeClass in allClasses)
{
// iterate all properties
var allProperties = VisualStudioHelper.GetAllCodeElementsOfType(codeClass.Members, EnvDTE.vsCMElement.vsCMElementProperty, true);
foreach(EnvDTE.CodeProperty property in allProperties)
{
// check if it is decorated with an "Input"-Attribute
if (property.Attributes.OfType<EnvDTE.CodeAttribute>().Any(a => a.FullName == "Input"))
{
...
}
}
}
#>

关于c# - 通过对同一程序集的反射生成代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15626157/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com