我有RazorEngine 3.4缓存的问题。我有几个电子邮件模板与相同的@Layout
但每个模板不同的Models
。它工作正常,直到我尝试使用不使用缓存的Cache I读取:"will result in both dreadful performances and memory leaks"
from here。
所以我打开了它。它很简单但导致了一个问题:_Layout.cshtml
也使用第一个模型类型进行缓存,当我尝试使用不同的模型解析另一个模板时,它会抛出异常:"System.ArgumentException: Object of type '....model1...' cannot be converted to type '...model2...'."
我在"IsolatedTemplateServiceTestFixture.cs"
写了2个单元测试来显示问题。第一个通过,但第二个通过,因为TemplateService.SetModelExplicit()
函数想要为Model
设置不同的Layout
类型的template.Model属性。
private Mock<ITemplateResolver> _templateResolver;
[Test]
public void IsolatedTemplateService_CanParseTemplateWithLayout_WithOneSerializableModels_UseCache()
{
_templateResolver = new Mock<ITemplateResolver>();
var config = new TemplateServiceConfiguration()
{
Resolver = _templateResolver.Object
};
using (var service = new TemplateService(config))
{
_templateResolver.Setup(i => i.Resolve("test")).Returns("<html>@RenderBody()</html>");
const string template = @"@{Layout=""test"";}<h1>Hello @Model.Item1</h1>";
const string expected = "<html><h1>Hello World</h1></html>";
var model = new Tuple<string>("World");
string result = service.Parse(template, model, null, "C1");
string result2 = service.Parse(template, model, null, "C1");
Assert.That(result == expected, "Result does not match expected: " + result);
Assert.That(result2 == expected, "Result does not match expected: " + result2);
}
}
[Test]
public void IsolatedTemplateService_CanParseTemplateWithLayout_WithDifferentSerializableModels_UseCache()
{
_templateResolver = new Mock<ITemplateResolver>();
var config = new TemplateServiceConfiguration()
{
Resolver = _templateResolver.Object
};
using (var service = new TemplateService(config))
{
_templateResolver.Setup(i => i.Resolve("test")).Returns("<html>@RenderBody()</html>");
const string template = @"@{Layout=""test"";}<h1>Hello @Model.Item1</h1>";
const string expected = "<html><h1>Hello World</h1></html>";
var model = new Tuple<string>("World");
string result = service.Parse(template, model, null, "C1");
string result2 = service.Parse(template, model, null, "C1");
const string template2 = @"@{Layout=""test"";}<h1>Hello2 @Model.Item1</h1>";
const string expected2 = "<html><h1>Hello2 123</h1></html>";
var model2 = new Tuple<int>(123);
string result3 = service.Parse(template2, model2, null, "C2");
Assert.That(result == expected, "Result does not match expected: " + result);
Assert.That(result2 == expected, "Result does not match expected: " + result2);
Assert.That(result3 == expected2, "Result does not match expected: " + result3);
}
}
我的问题是:任何人都有同样的问题吗?什么是一个“好”的方法来解决它,直到它将被修复(如果它发生)?
更新:
使用最新版本(目前是v.3.10),两个测试都通过了。所以问题得到解决。
与RazorEngine一样,即使您未在其中声明模型,布局也具有固定类型。第一次通过编译模板编译布局时,模板的模型类型也成为布局的类型。正如您所注意到的,当您尝试使用其他类型编译另一个模板时,这将发生冲突。
您可以通过声明布局动态的模型类型(即@model dynamic
)来解决这个问题
这应该够了吧。实际模板不需要更改。