在 T4 中使用来自单独 class 库的扩展方法
Using extension methods from a separate class library in T4
我创建了一个 class 库,其中包含用于处理 EnvDTE
对象的扩展方法。示例扩展方法是:
namespace EnvDTE.Extensions
{
public static class DTEExtensions
{
public static Project CurrentProject (this DTE dte)
{
return dte.ActiveDocument.ProjectItem.ContainingProject;
}
}
}
当我尝试在我的 T4 文件中使用扩展方法时:
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="EnvDTE" #>
<#@ assembly name = "$(SolutionDir)..\..\Windows\EnvDTE.Extensions\EnvDTE.Extensions\bin\Debug\EnvDTE.Extensions.dll" #>
<#@ assembly name = "System.Core" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="EnvDTE.Extensions" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<#
var serviceProvider = (IServiceProvider)this.Host;
var dte = serviceProvider.GetService(typeof(DTE)) as DTE;
var project = dte.CurrentProject();
#>
namespace <#= project.Properties.Item("DefaultNamespace").Value #>
{
}
我得到以下异常:
Severity Code Description Project File Line
Error Running transformation: System.Runtime.Remoting.RemotingException: Cannot load type 'EnvDTE._DTE, EnvDTE.Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Server stack trace:
at System.Runtime.Remoting.Messaging.MethodCall.ResolveMethod(Boolean bThrowIfNotResolved)
at System.Runtime.Remoting.Messaging.MethodCall..ctor(SmuggledMethodCallMessage smuggledMsg, ArrayList deserializedArgs)
at System.Runtime.Remoting.Channels.CrossAppDomainSink.DoDispatch(Byte[] reqStmBuff, SmuggledMethodCallMessage smuggledMcm, SmuggledMethodReturnMessage& smuggledMrm)
at System.Runtime.Remoting.Channels.CrossAppDomainSink.DoTransitionDispatchCallback(Object[] args)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at EnvDTE._DTE.get_ActiveDocument()
at EnvDTE.Extensions.DTEExtensions.CurrentProject(DTE dte) in D:\Users\Adaptive\Projects\Windows\EnvDTE.Extensions\EnvDTE.Extensions\DTEExtensions.cs:line 13
at Microsoft.VisualStudio.TextTemplating0BE14095FFF8852C1DA8AAA0F831675849ECBB71E2A8B8BA2027BD64107CEDE73824E8CF863A0048B6B5FF80E64944B13E838B3338BD67CA7B6A2CF9BB4BD07C.GeneratedTextTransformation.TransformText() TicketTracker D:\Users\Adaptive\Projects\Universal\TicketTracker\TicketTracker\Models\HoursModel.tt 1
知道我做错了什么吗?看起来转换引擎正在错误的库中查找类型。我知道我可以通过导入各种 T4 文件来创建我的扩展方法的集合,但如果可以的话,我更喜欢 class 库。
我没有测试过,但是根据这个 blog post 当你将语言属性设置为 "C#" 或 "VB" T4 将使用 2.0 框架但是如果你使用 "C#v3.5" 或 "VBv3.5" 它将使用应该允许您使用扩展方法的 3.5 框架。
所以,问题是使用我的扩展方法的程序集嵌入了 Interop 类型。我必须关闭它才能使我的扩展方法起作用:
我创建了一个 class 库,其中包含用于处理 EnvDTE
对象的扩展方法。示例扩展方法是:
namespace EnvDTE.Extensions
{
public static class DTEExtensions
{
public static Project CurrentProject (this DTE dte)
{
return dte.ActiveDocument.ProjectItem.ContainingProject;
}
}
}
当我尝试在我的 T4 文件中使用扩展方法时:
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="EnvDTE" #>
<#@ assembly name = "$(SolutionDir)..\..\Windows\EnvDTE.Extensions\EnvDTE.Extensions\bin\Debug\EnvDTE.Extensions.dll" #>
<#@ assembly name = "System.Core" #>
<#@ import namespace="EnvDTE" #>
<#@ import namespace="EnvDTE.Extensions" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<#
var serviceProvider = (IServiceProvider)this.Host;
var dte = serviceProvider.GetService(typeof(DTE)) as DTE;
var project = dte.CurrentProject();
#>
namespace <#= project.Properties.Item("DefaultNamespace").Value #>
{
}
我得到以下异常:
Severity Code Description Project File Line
Error Running transformation: System.Runtime.Remoting.RemotingException: Cannot load type 'EnvDTE._DTE, EnvDTE.Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
Server stack trace:
at System.Runtime.Remoting.Messaging.MethodCall.ResolveMethod(Boolean bThrowIfNotResolved)
at System.Runtime.Remoting.Messaging.MethodCall..ctor(SmuggledMethodCallMessage smuggledMsg, ArrayList deserializedArgs)
at System.Runtime.Remoting.Channels.CrossAppDomainSink.DoDispatch(Byte[] reqStmBuff, SmuggledMethodCallMessage smuggledMcm, SmuggledMethodReturnMessage& smuggledMrm)
at System.Runtime.Remoting.Channels.CrossAppDomainSink.DoTransitionDispatchCallback(Object[] args)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at EnvDTE._DTE.get_ActiveDocument()
at EnvDTE.Extensions.DTEExtensions.CurrentProject(DTE dte) in D:\Users\Adaptive\Projects\Windows\EnvDTE.Extensions\EnvDTE.Extensions\DTEExtensions.cs:line 13
at Microsoft.VisualStudio.TextTemplating0BE14095FFF8852C1DA8AAA0F831675849ECBB71E2A8B8BA2027BD64107CEDE73824E8CF863A0048B6B5FF80E64944B13E838B3338BD67CA7B6A2CF9BB4BD07C.GeneratedTextTransformation.TransformText() TicketTracker D:\Users\Adaptive\Projects\Universal\TicketTracker\TicketTracker\Models\HoursModel.tt 1
知道我做错了什么吗?看起来转换引擎正在错误的库中查找类型。我知道我可以通过导入各种 T4 文件来创建我的扩展方法的集合,但如果可以的话,我更喜欢 class 库。
我没有测试过,但是根据这个 blog post 当你将语言属性设置为 "C#" 或 "VB" T4 将使用 2.0 框架但是如果你使用 "C#v3.5" 或 "VBv3.5" 它将使用应该允许您使用扩展方法的 3.5 框架。
所以,问题是使用我的扩展方法的程序集嵌入了 Interop 类型。我必须关闭它才能使我的扩展方法起作用: