编写T4模板进行代码生成无法避免的两个话题:"Assembly Lock
在这之前,我写了一系列关于代码生成和T4相关的文章,而我现在也试图将T4引入我们自己的开发框架。在实践中遇到了一些问题,也解决了不少问题。如果你也在进行T4相关的开发,相信你也一定会遇到这些问题。为此,特意将这些问题和解决方案与朋友们分享,希望在遇到这些问题的时候少走弯路。本篇文章介绍的是两个重要的话题:程序集锁定和调试。
一、程序集引用导致的编译问题如果你看过我上一篇文章,你应该知道我们至少具有解决T4模板的程序集引用的五种方案,在这里我们采用的是VS宏的解决方案,即将引用程序集文件的路径设置成通过$(SolutionDir)表示的解决方案目录的相对路径。HelloWorld.tt定义如下,引用的程序集路径为Lib项目在Debug模式下编译生成的目录($(SolutionDir)LibBinDebug)。 <#@ template debug="true" hostSpecific="true" #> <#@ output extension=".cs" #>
<#@ Assembly name="$(SolutionDir)LibBinDebugArtech.T4Template.Lib.dll" #>
using System;
{ static void Main() { <# foreach( var person in Artech.T4Template.HelloWorldHelper.GetPersons()) {#> Console.WriteLine("Hello,{0}!","<#=person#>"); <# } #> } } 当你保存该T4模板,T4引擎将触发并进行代码生成工作,但是此时如果你试图编译被引用(实际上是生成的程序集被引用)的Lib项目,将会出现如下所示的编译错误。错误信息为:“Unable to copy file "objDebugArtech.T4Template.Lib.dll" to "binDebugArtech.T4Template.Lib.dll". The process cannot access the file 'binDebugArtech.T4Template.Lib.dll' because it is being used by another process.”,即之前生成的程序集正在被使用,所以不能将生成的程序集拷贝到编译目标目录下。 二、T4引擎对引用程序集的锁定实际上这个程序集的使用者正是T4引擎。出于提高性能考虑,T4引擎在进行基于代码生成的模板转换(Template Transformation)的时候,会始终重用同一个AppDomain。由于该AppDomain不会自动卸载,这就会导致该AppDomain始终锁定所有被它加载的程序集。如果我们需要释放程序集,我们不得不重启VS。但是,对于T4模板的开发调试阶段,这种通过重新启动VS的方式去释放程序集以确保我们的项目能够成功编译是不能接受的。 那么,是否有一种解决方案既能够确保T4引擎能够进行正常的模板转换,又能避免它强行锁定引用程序集呢?如果你采用T4 ToolBox,你可以通过<#@ VolatileAssembly…#>这个指令轻松地解决这个问题。下面的T4模板中,我们将通过<#@Assembly…#>指令的程序集引用方式替换成了<#@ VolatileAssembly…#>(<#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor"? name="$(SolutionDir)LibBinDebugArtech.T4Template.Lib.dll" #>),我们的Lib项目在任何时候都可以自由地编译。 <#@ VolatileAssembly processor="T4Toolbox.VolatileAssemblyProcessor" name=创建一个新的程序集拷贝。 |
- asp.net-mvc – 存在哪些ASP.NET MVC示例项目?
- asp.net-mvc – 如何将Telerik ComboBox中的数据绑定到我的
- 为什么这会考虑不好的做法?或者是吗? (ASP.Net)
- ASP.NET -- WebForm -- .aspx与.aspx.cs文件
- asp.net – MVC3 Razor – 到期页面
- 我可能正在开发一个ASP.NET应用程序. Java / PHP开发人员在
- asp.net-mvc-4 – MVC 4 Html.EditorFor无效
- asp.net – Visual Studio不识别新类
- asp.net-mvc-3 – 无法解析属性:User.Full_Name of:Harro
- 使用asp.net和vb.net从sql server导出到excel文件?
- asp.net-mvc-3 – PrepareResponse().AsActionRe
- asp.net-mvc-2 – 使用.Net Framework 4.0的Shar
- asp.net-mvc – 使用ASP.NET MVC响应HTTP HEAD请
- ASP.NET Webdeploy失败;项目中不存在AddSchedule
- asp.net-mvc – 何时将MVC视图拆分为两个?
- ASP.NET MVC编辑器模板和Html.EditorFor(…) –
- asp.net-mvc – MVC 4 _Layout.cshtml viewmodel
- asp.net – LINQ查询,其中boolean值为true或fals
- asp.net-mvc – 如何在单个页面中使用两个AntiFo
- asp.net – 嵌套的Repeater和SqlDataSource参数