abpframework / abp

Open-source web application framework for ASP.NET Core! Offers an opinionated architecture to build enterprise software solutions with best practices on top of the .NET. Provides the fundamental infrastructure, cross-cutting-concern implementations, startup templates, application modules, UI themes, tooling and documentation.
https://abp.io
GNU Lesser General Public License v3.0
12.47k stars 3.36k forks source link

About Inline localization in template engines #19934

Open colinin opened 1 month ago

colinin commented 1 month ago

Is there an existing issue for this?

Is your feature request related to a problem? Please describe the problem.

I noticed that the template engine rendering is already asynchronous, but when I use an asynchronous inline localization resource, it will cause rendering failure because it usesStringLocalizerFactory.CreateByResourceName

Affected Code: https://github.com/abpframework/abp/blob/b46dfa722a36b3bd9cd903def1793b114ca639b4/framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/TemplateRenderingEngineBase.cs#L32-L40

Describe the solution you'd like

Replacing synchronous functions with asynchronous localized resources

example:

public abstract class TemplateRenderingEngineBase : ITemplateRenderingEngine
{
    public abstract string Name { get; }

    protected readonly ITemplateDefinitionManager TemplateDefinitionManager;
    protected readonly ITemplateContentProvider TemplateContentProvider;
    protected readonly IStringLocalizerFactory StringLocalizerFactory;

    public TemplateRenderingEngineBase(
        ITemplateDefinitionManager templateDefinitionManager,
        ITemplateContentProvider templateContentProvider,
        IStringLocalizerFactory stringLocalizerFactory)
    {
        TemplateDefinitionManager = templateDefinitionManager;
        TemplateContentProvider = templateContentProvider;
        StringLocalizerFactory = stringLocalizerFactory;
    }

    public abstract Task<string> RenderAsync(string templateName, object? model = null, string? cultureName = null, Dictionary<string, object>? globalContext = null);

    protected virtual async Task<string?> GetContentOrNullAsync(TemplateDefinition templateDefinition)
    {
        return await TemplateContentProvider.GetContentOrNullAsync(templateDefinition);
    }

    protected async virtual Task<IStringLocalizer?> GetLocalizerOrNullAsync(TemplateDefinition templateDefinition)
    {
        if (templateDefinition.LocalizationResourceName != null)
        {
            return await StringLocalizerFactory.CreateByResourceNameOrNullAsync(templateDefinition.LocalizationResourceName);
        }

        return StringLocalizerFactory.CreateDefaultOrNull();
    }
}

Additional context

No response

maliming commented 1 month ago

but when I use an asynchronous inline localization resource,

Can you share your code?

colinin commented 3 weeks ago

but when I use an asynchronous inline localization resource,

Can you share your code?

After several tests, I believe it is due to the unreasonable design of my IExternalLocalizationStore interface implementation. The problem is that the template engine runs before the initialization of IExternalLocalizationStore