FluentEmail icon indicating copy to clipboard operation
FluentEmail copied to clipboard

Calls like `UsingTemplateFromEmbedded` should use the RazorLight engine instead of `EmbeddedResourceHelper.GetResourceAsString`

Open VictorioBerra opened this issue 5 years ago • 1 comments

Because of this: https://github.com/lukencode/FluentEmail/blob/master/src/FluentEmail.Core/Email.cs#L306

This goes basically unused. https://github.com/lukencode/FluentEmail/blob/master/src/Renderers/FluentEmail.Razor/RazorRenderer.cs#L35

This is because the RazorRenderer implementation in FluentEmail treats all templates a strings.

We need methods like ParseAsync but that defer to RazorLight like ParseEmbeddedAsync which would call CompileRenderAsync which takes a namespace.

Ref https://github.com/lukencode/FluentEmail/pull/240

VictorioBerra avatar Jan 19 '21 23:01 VictorioBerra

Here is a simple implementation, we could include this in the code.

namespace YourApp
{
    using System;
    using System.Threading.Tasks;
    using FluentEmail.Core.Interfaces;
    using RazorLight;

    /// <summary>
    /// Very similar to <see cref="FluentEmail.Razor.RazorRenderer"/> but for RazorLight configured to use embedded resources.
    /// </summary>
    public class EmbeddedRazorRenderer : ITemplateRenderer
    {
        private readonly RazorLightEngine engine;

        /// <summary>
        /// Initializes a new instance of the <see cref="EmbeddedRazorRenderer"/> class.
        /// Configures RazorLight to use a project whose persistent store an assembly manifest resource stream.
        /// </summary>
        /// <param name="embeddedResRootType">Any type in the root namespace (prefix) for your assembly manifest resource stream.</param>
        /// <remarks>Docs borrowed from RazorLight UseEmbeddedResourcesProject.</remarks>
        public EmbeddedRazorRenderer(Type embeddedResRootType)
        {
            this.engine = new RazorLightEngineBuilder()
                .UseEmbeddedResourcesProject(embeddedResRootType)
                .UseMemoryCachingProvider()
                .Build();
        }

        /// <inheritdoc/>
        public async Task<string> ParseAsync<T>(string template, T model, bool isHtml = true) => await this.engine
            .CompileRenderAsync(template, model)
            .ConfigureAwait(false);

        /// <inheritdoc/>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD002:Avoid problematic synchronous waits", Justification = "This is required to satisfy ITemplateRenderer implemenation")]
        public string Parse<T>(string template, T model, bool isHtml) => this.ParseAsync(template, model, isHtml)
            .GetAwaiter()
            .GetResult();
    }
}

VictorioBerra avatar Jan 20 '21 00:01 VictorioBerra