自定义T4预处理模板

时间:2012-05-24 14:31:55

标签: c# t4

我正在尝试做什么

我正在尝试使用T4创建邮件消息模板。

我正在使用预处理模板,如果我没有正确使用,那么如果我想在运行时生成消息而不引入对{{1}的依赖,我就必须这样做组装。

由于我想将一些数据传递给我的模板,我向其添加了参数:

Microsoft.VisualStudio.TextTemplating

然后我可以像这样生成传递参数的消息:

<#@ template language="C#" #>
<#@ parameter name="Param1" type="System.String" #>
<#@ parameter name="Param2" type="System.    
Lorem <#= Param1 #> dolor <#= Param2 #>

有什么问题

由于我需要生成其中的几个类,我希望他们都有一个通用的方法来发送邮件,如下所示:

static void Main(string[] args) {
    var template = new LoremIpsum();
    template.Session = new Dictionary<string, object>() { 
        {"Param1", "ipsum"},
        {"Param2", "sit amet"},
    };
    template.Initialize();
    string text = template.TransformText();
}

或者,甚至更好:

public void SendMail(string to, IDictionary<string, object> parameters)

由于生成的类是部分的,因此可以向它们添加添加另一个部分类声明的方法,但这意味着我必须为所有生成的类重复(或多或少)相同的代码。

到目前为止我尝试了什么

我尝试创建基类,但如果我尝试这样做:

public void SendMail(string to, string Param1, string Param2)

然后生成的代码中断,因为生成的类依赖于定义了一些辅助方法的<#@ template language="C#" inherits="MailTemplateBase" #> 基类(我真的认为每个生成的类继承自几乎相同但不同的基类没有意义)。

问题

  1. 如何为我的模板设置基类?
  2. 如何生成一个接受与模板中声明的参数相同的参数的方法?

2 个答案:

答案 0 :(得分:2)

我认为您需要创建一个空模板,复制创建的类并将其用作基类。然后,您可以使用您需要的任何属性扩展它。 (复制代码后,您不需要保留空模板)

我认为你想要做的事情在VS 2010 RTM中开箱即用,但VS2010 SP1改变了行为,因此你可以自己创建模板子类。有关详细信息,请查看此connect issue

编辑:

就基础上放一个电子邮件方法而言,我可能不会这样做。您可能想要考虑暴露某种模板服务,该服务具有您需要的各种方法,例如:

public class TemplatingService : ITemplatingService
{
    public string GenerateReminderMessage(string to, string name)
    {
        // Construct the template, passing in the parameters into the session as required
        ...
        // Return the results of the template transformation
    }
}

这样你就可以从实际的T4实现中抽象出来,所以如果某些东西确实在某个地方破坏了你只需要在一个类中修复它。

并公开使用模板服务生成邮件内容的邮件服务:

public class MailService : IMailService
{
    public void SendReminderEmail(string to, string name)
    {
        var message = this.TemplatingService.GenerateReminderMessage(to, name);
        this.MailerService.SendEmail(to, message);
    }
}

请注意,MailerService只是一个围绕.NET邮件代码的简单包装器,但它允许您单独测试MailService。

可能有更多方法可以将其抽象出来,但这将是一个开始。

希望有所帮助。

答案 1 :(得分:0)

听起来你假设构造函数注入是将数据注入类的唯一方法。我想在这种情况下,metod / property注入是更好的选择。

我手边没有编译器,无法确认,但似乎可能有效。