【问题标题】:How can I use roslyn from a t4 template to parse the current solution?如何使用 t4 模板中的 roslyn 解析当前解决方案?
【发布时间】:2015-12-13 02:44:49
【问题描述】:

如何从 T4 模板中获取当前会话的 VisualStudioWorkspace 实例?我希望它能够解析当前解决方案中的源文件(即 .tt 文件所在的解决方案)。

从 VS 包中,我可以使用 GetService(SComponentModel) 并从中获取工作区实例,但是使用以下代码时,这似乎会在 T4 文件中生成错误:

IServiceProvider serviceProvider = (IServiceProvider)this.Host;
var comp = serviceProvider.GetService(typeof(SComponentModel)) as IComponentModel;

返回的错误是: System.Runtime.Serialization.SerializationException: Type 'Microsoft.VisualStudio.ComponentModelHost.ComponentModel' in Assembly 'Microsoft.VisualStudio.ComponentModelHost.Implementation, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' is not marked as serializable.

【问题讨论】:

  • IIRC,T4不在VS进程中运行;这可能是不可能的。
  • 嗯.. 这听起来很烦人,而且有点奇怪。毕竟,您可以在 T4 模板中从 DTE 访问 FileCodeModel,而我认为这些天这是在 Roslyn 之上实现的?
  • 要么我错了,要么只能通过跨进程 COM 编组工作。
  • 这太令人失望了。那么在这种情况下,VSPackage中的单个文件生成器是这种情况下生成代码的唯一选择,需要每个开发人员都安装VS扩展?
  • 我完全错了。

标签: c# visual-studio-2015 t4 roslyn


【解决方案1】:

您可以通过设置hostspecific="true",然后将this.Host 转换为IServiceProvider,从T4 访问VS IServiceProvider

Details

但是,这实际上不起作用,因为您的 T4 代码在单独的 AppDomain 中运行,而 MEF 和 Roslyn 对象将无法使用它。将MarshalByRefObject 注入主 VS AppDomain 可能会起作用。

【讨论】:

  • 是的,我知道这一点。但是,如果我尝试获取 SComponentModel 服务(获取我的 VisualStudioWorkspace),我会收到一条错误消息,指出某些类型不可序列化。
  • 我用我使用的代码和我得到的错误更新了问题。
  • @DeCaf:啊;看起来 T4 在单独的 AppDomain 中运行(这是有道理的,因为它应该被卸载)。你不走运,除非你写一个MarshalByRefObject 包装器并将它加载到原始的AppDomain 中(这可能并不容易)。
  • 我害怕那个。猜猜我将不得不将我的生成代码编写为 VSIX 包。如果您使用此信息更新您的答案,我会将此问题标记为已回答。感谢您的意见!
猜你喜欢
  • 2011-06-24
  • 1970-01-01
  • 2011-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多