我有一個對象u1
類型User
類。用戶有一個屬性name
。如何將u1
傳遞給T4模板?我試圖做一些很簡單:將對象傳遞給T4模板
User u1 = new User("John");
模板腳本:
Hello <# u1.Name #>
我有一個對象u1
類型User
類。用戶有一個屬性name
。如何將u1
傳遞給T4模板?我試圖做一些很簡單:將對象傳遞給T4模板
User u1 = new User("John");
模板腳本:
Hello <# u1.Name #>
你想在你的模板中使用它?然後,您需要添加對包含該類型的程序集的引用。你不能簡單地將現有的引用傳遞給T4引擎,除非你以一種非正統的方式自己託管它(我從來沒有見過任何人試圖這樣做)。即使你走得太遠了,你會怎麼做呢?這個參考文獻應該來自哪裏?
使用T4模板中的類型與添加引用或將其複製/粘貼到類存根<#+ /*stuff goes here*/ #>
一樣簡單。
T4模板在一個步驟中進行處理,以便模板在其運行期間需要獲取所需的所有內容,因爲您並不真正「傳遞」任何內容。由於模板是文本,我通常只需要一些開發人員可以在文件頂部設置的參數。如果你需要用戶輸入,你可以有一個窗口彈出窗口,但生成代碼時聽起來很煩人。
另一種解決方案是使用一個自定義模板,該模板在t4模板中使用模板替換,類似於大量已安裝模板的工作方式。
如你所知,我只是開始,很多黑暗。但是,最終,我想要做的是,創建一個模板的編譯對象,並引用一個user類型的對象。當模板最終運行時,它將使用對象的屬性來輸出文本。 – brainydexter 2011-05-31 19:02:03
嘿 - 你需要設置T4腳本中值等,所以User
初始化必須發生在<# #>
標籤,它會變成你到例如類似的東西來
<# User u1 = new User() { .Name = "John" } #>
Hello <# u1.Name #>
正如上面可能還提到內部需要導入命名空間。我已經在TT-文件的開始時使用的語句下面去System.Data訪問:
<#@ import namespace="System.Data" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ assembly name="System.Data" #>
假設你想在某些應用程序或工具,最終運行的模板,然後使用運行時(代碼預處理的)模板或者在<#+#>類功能塊或<#@參數#>指令中定義的自定義屬性應該給你想要的。
看一看這裏的文檔:http://msdn.microsoft.com/en-us/library/gg586944.aspx
感謝您的回覆。我們決定不使用T4,因爲它限制我們使用主機VS環境或調用T4引擎的外部執行程序。規模是我們主要關心的問題,並且每次調用外部執行人員都是一種我們無法承受的非常操作。請讓我知道是否有解決方法,因爲我非常喜歡T4的強大功能,完全符合我們正在做的事情,但在這方面限制了我們。 – brainydexter 2011-06-20 18:53:44
預處理的tempaltes不需要主機VS.如果您的模板文本在構建時已修復,則應該按照您的需要進行操作。 – GarethJ 2011-06-20 20:37:50
我們做了類似的措施。我們的解決方案具有以下元素:
自定義主機由模板本身想調用方法的對象聚合。現在
interface ICallbackInterface
{
void CallbackFxn();
}
[Serializable]
public class MyCustomHost : ITextTemplatingEngineHost, ITextTemplatingSessionHost, IStencilFileRecordManagement
{
private ICallbackInterface callback = null;
public MyCustomHost(ICallbackInterface cb)
{
callback = cb;
}
public void CallbackFxn()
{
callback.CallbackFxn();
}
}
public abstract class MyTemplateBase : TextTransformation
{
public virtual MyCustomHost CustomHost
{
get
{
dynamic metame = this;
MyCustomHost rval = null;
try
{
/// <summary>
/// The "Host" property will be added to the generated class by the T4 environment whenever a
/// "hostspecific" template is processed.
/// </summary>
rval = metame.Host as MyCustomHost;
}
catch (RuntimeBinderException e)
{
logger.ErrorException(
"Received the following exception while processing a stencil template", e);
}
return rval;
}
}
}
,內我們的任何模板,我們可以調用實際使用自定義主機屬性誰拉開帷幕處理的對象,如上的方法:
<# CustomHost.CallbackFxn(); #>
而且,我們不使用T4中的VS或使用單獨的可執行文件 - 我們鏈接到Microsoft.VisualStudio.TextTemplating.10.0和Microsoft.VisualStudio.TextTemplating.Interfaces.10.0程序集。
編輯
我們使用T4模板允許用戶定義在我們的產品工作流程中的特定步驟中使用自己的插件。因此,用戶模板上傳到我們的系統,並處理這樣的:
using Microsoft.VisualStudio.TextTemplating;
class UserPluginWorkflowComponent : ICallbackInterface
{
public void CallbackFxn()
{
// invoked by user plugin
}
public void ExecuteUserPlugin()
{
MyCustomHost host = new MyCustomHost(this);
host.TemplateFileValue = "UserPluginTemplateFilename";
Engine engine = new Engine();
string pluginResult = engine.ProcessTemplate(
userPluginTemplateFileContents,
host);
if (!host.Errors.HasErrors)
{
// use pluginResult in some meaningful way
}
}
}
你能說一下嗎?顯示對象如何「啓動處理」? – 2011-09-10 01:41:31
我瞭解一些你在說什麼,但請你在此展開:'你不能簡單地通過現有的參考T4引擎,除非你的主機它自己'?另外,只是想讓你知道,.tt文件和用戶類都是同一解決方案的一部分。 – brainydexter 2011-05-31 19:04:32
對。那麼沒有辦法交出參考。 T4模板實際上運行在它自己的域中。有幾個原因。如果您承載T4處理,您應該能夠傳遞處理引用,但這不是我以前見過的任何人。最好的辦法是將程序集引用到您希望使用的程序集或添加它,作爲T4類存根的一部分。奧列格Sych博客關於T4,看那裏的詳細信息如何做到這一點http://www.olegsych.com/2008/02/t4-assembly-directive/ – 2011-05-31 19:17:30