来自散列(sha1)模板的Razorengine唯一模板名称?

时间:2015-05-26 10:58:02

标签: c# .net email razorengine

我有两个完全独立的网络(api)服务。

一个类似于商业案例(bc),另一个只关注发送(和构建)电子邮件(ms)< /强>

所以基本上BC会将所有相关数据发送到邮件服务。

BC ===== { Sender, Receipient, Subject, Template, Model } =====> MS

邮件服务采用模板(剃刀模板)和模型并构建邮件的内容。它对于也可能是剃刀模板的主题也是如此。

现在的问题是......为了让razorengine正常工作......我需要为我的邮件模板指定唯一的名称,我不想信任这个任务的商业案例。因为客户端可能会选择另一个客户端(业务案例)已使用的名称。

我现在的解决方案如下:

string uniqueTemplateName = sha1(template); // bad idea?
string result = _razorEngineService.RunCompile(template, uniqueTemplateName, null, (object)model);

使用sha1(template)应该可以做到这一点,对吧? 这有什么缺点吗?

1 个答案:

答案 0 :(得分:0)

根据您的要求,您实际上有几个问题。 最初看起来像“clientname / templatename”是合适的。 通常只使用模板来自的路径(完整目录路径,数据库ID)。

任何类型的哈希都完全违背了缓存层的目的,以便您能够注意到由于过时的模板需要回收当前的AppDomain。默认的CachingProvider将始终使用缓存的条目,并且将忽略更改(不重新编译)。但您可以根据自己的需要进行定制。例如,您可以实施以下策略:如果编辑单个模板超过10次,则回收AppDomain。可以通过实现ITemplateManagerICachingProvider以及一些AppDomain回收代码来实现此目的。如何做到这一点有点超出了您提出的问题的范围,但您可以查看现有的实现。

这个AppDomain回收的东西很难,用哈希打败它似乎是一个简单的解决方案,但如果你需要更改模板,你需要考虑它,因为我们无法从你那里抽象出来(因为加载程序集无法卸载)。根据您的用户和环境,您可能会遇到这样的情况:用户可以通过填充内存来启动对服务的DOS攻击。如果你对性能很好,你也可以查看隔离API。通过隔离,您可以使用非常简单的方法,例如每1000次编译回收AppDomain(您仍然需要使用自定义ICachingProvider自行实现通知,或者更简单地计算您使用RunCompile的次数

TL; DR缺点:

  • 碰撞(见Eric Lippert的评论)
  • 无法找到/注意陈旧模板
  • - &GT; DOS情况

希望这有帮助,

matthid(Disclosure:A RazorEngine Contributor)