【问题标题】:How to update resource files without recompiling如何在不重新编译的情况下更新资源文件
【发布时间】:2021-06-25 11:16:13
【问题描述】:

我有一个带有本地化功能的 .net 核心 Web 应用程序。我有带有翻译的 .resx 文件。另外,我有一个 api,可以下载新版本的翻译。旧版本正在被新版本取代,但要更新应用程序中的资源,我需要重新编译它。这可以不重新编译吗?也许我需要重建资源 dll?

【问题讨论】:

  • 这取决于网络版本和编译模式(16/32/64)。 Net dll 需要与用于编译的同一版本的 Net 才能在机器上运行。
  • 您可以创建自己的资源提供程序并从数据库中加载它们。查看 nopcomerce 的源代码,它会详细地向您展示如何实现这一点。通过研究他们的方法,我能够做到这一点
  • 如果您想直接使用 .resx 文件而不编译它们,您可以使用 this 库(免责声明:由我编写)。它有一个ResXResourceManager 类,可以用作普通的ResourceManagerHybridResourceManager 支持使用 .resx 文件覆盖已编译的资源(如果存在),最后,DynamicResourceManager 支持在您切换到尚未设置保存资源的语言时生成资源文件。
  • @GyörgyKőszeg 我将 HybridResourceManager 与 CompiledAndResX 一起使用,它编辑 resx 文件,但不是 dll。我仍然需要重新编译应用程序
  • HybridResourceManager 可以从 .dll 中读取已编译的资源,并且可以读取和写入 .resx 文件。在CompiledAndResX 模式下,首先访问 .resx 内容,因此您甚至可以通过部署相同语言的 .resx 文件来覆盖已编译的资源。所以它编辑 dll。但它可以直接使用 resx 文件,因此您不需要将它们编译成卫星资源 dll 文件。这不是你要求的吗?使用 .resx 文件而不需要编译它们?

标签: c# .net .net-core dll resources


【解决方案1】:

创建您自己的剃须刀页面,所有其他页面都将从中派生。

要记住的一点是,它会提取到数据库中,但我认为它只是在编译时或页面刷新时。

public abstract class CellaRazorPage<TModel> : Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>
{
     private Localizer _localizer;       

    /// <summary>
    /// Get a localized resources
    /// </summary>
    public Localizer T
    {
        get
        {
            var serviceProviderContext = Context.RequestServices.GetRequiredService<CellaDBContext>();
            Int32.TryParse(serviceProviderContext.Appsettings.Where(w => w.Key == Constants.FrontEndDefaultLanguageId).FirstOrDefault().Value, out int defaultLangId);
            var serviceProvider = Context.RequestServices.GetRequiredService<ILocalizationService>();
            

            if (_localizer == null)
            {
                _localizer = (format, args) =>
                {  //we want to set the default langauge id here so whatever the user sets will always be shown.
                    var resFormat = serviceProvider.GetResourceAsync(format, defaultLangId).Result;
                    if (string.IsNullOrEmpty(resFormat))
                    {
                        return new LocalizedString(format);
                    }
                    return new LocalizedString((args == null || args.Length == 0)
                        ? resFormat
                        : string.Format(resFormat, args));
                };
            }
            return _localizer;
        }
    }

}

 /// <summary>
 /// Web view page
 /// </summary>
 public abstract class CellaRazorPage : CellaRazorPage<dynamic>
 {
 }
}

数据库调用有这样的东西 本地化服务

public virtual async Task<string> GetResourceAsync(string resourceKey, int langugeID)
{
    var result = await _context.LocaleStringResource.Where(w => w.ResourceName == resourceKey && w.LanguageId == langugeID && w.isDeleted == false && w.isActive == true).FirstOrDefaultAsync();
        var resultString = string.Empty;
        if (result != null)
            resultString = result.ResourceValue;
        else
            resultString = resourceKey;
        return resultString;
}

用法

@T("搜索")

这意味着您可以从数据库中实时更新字符串,并且在下次刷新时它将包含新字符串而无需重新启动。

我忘了提到语言会这样存储。您可以将其保存在 cookie 或您的应用设置语言 ID 中,或者如果来自像我这样的国家/地区选择器。

将此处的 id 保存在 cookie 中

你可以在这里存储你的字符串

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-21
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    相关资源
    最近更新 更多