Closed lwansbrough closed 3 years ago
Not sure what you're asking. - How to compile a template that has no model?
Just use a phantom model with type @Model System.Object
That's basically what I did. Seems to work, just wasn't sure if that was a good idea or not. My question was about whether it was possible to compile without a model at all. For instance, it would be useful to be able to do something like this:
var templateSource = "@Model MyType\n<html/>";
var template = await CompileStringAsync("key", templateSource);
var rendered = await _razorEngine.RenderTemplateAsync(template, myTypeInstance, typeof(MyType));
This way I don't have to know the model type at compile time. This allows me to re-render the compiled template without having to recompile each time. (My use case is allowing dynamically created email templates to be batched to many users with templating in an efficient way.)
Interesting, thanks for sharing. I'll think about it. If you have a solution, please post it here for further discussion.
I think that when you use CompileRenderStringAsync (shown in quick start), it will be compiled and rendered when run for first time, and in following calls it will use precompiled templates. I think it works like that, because why else would there be a caching provider?
If I am correct, you do not need to precompile the templates beforehand, it will be done in first render. If you really need the precompilation, you can compile-render each template with a model created just for precompilation.
@lwansbrough
This way I don't have to know the model type at compile time. This allows me to re-render the compiled template without having to recompile each time. (My use case is allowing dynamically created email templates to be batched to many users with templating in an efficient way.)
I think you might be conflating two requirements in your design.
For one, this is a common feature request for ASP.NET Razor, but Microsoft hasn't addressed it. Basically, you can't create a template on an "open generic". For example, Razor doesn't support @Model IEnumerable<T>
. Support for open generics would likely also be "templating in an efficient way", since it would internalize a lot of details to the JIT, which has very efficient support for compiling generically typed code.
For two, I have a very hard time believing its more efficient to generate a template the way you're describing. Even so, just use a phantom type and pass a singleton value to RazorLight. If you want to cache the output for a given template key, use a fast, in-memory caching framework like Microsoft Research's FASTER.
Ordinarily, the way Razor supports model-less Views is through ViewBags, but that approach is most likely NOT efficient since it uses ExpandoObject
s, rather than a class property/function which is simply a pointer-to-member-function in a C++ v-table. I'd have to see more of your code to weigh in with more advice.
Is a method like
Task<ITemplatePage> CompileStringAsync(string key, string source)
possible?