·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> ASP.NET网站开发 >> [Asp.net 5] Localization-resx资源文件的管理

[Asp.net 5] Localization-resx资源文件的管理

作者:佚名      ASP.NET网站开发编辑:admin      更新时间:2022-07-23

[asp.net 5] Localization-resx资源文件的管理

上一篇博文地址:[Asp.net 5] Localization-简单易用的本地化-全球化信息

本文继续介绍asp.net 5多语言。今天重点讲的是多语言的resx文件。涉及到的工程有:Microsoft.Framework.Localization.Abstractions以及Microsoft.Framework.Localization。他们之间的类结构如下如所示:

  • Abstractions包中,包含了定义在工程Microsoft.Framework.Localization.Abstractions的大部分类和接口
  • Localization包中,包含了定义在工程Microsoft.Framework.Localization中的大部分类和接口

Microsoft.Framework.Localization.Abstractions

该工程定义了本地化(全球化)的基本接口,以及一些抽象类。

  • LocalizedString 封装name、value等属性的结构体,用于表示本地化寻找的结果
  • IStringLocalizer 本地化访问的基本接口,通过方法或者属性(通过扩展方法,使得方法和属性调用一套逻辑)获得LocalizedString结构体对象;本解决方案中,对资源文件就是该接口的 实例操作的
  • IStringLocalizer<T> 本接口中未定义任何方法,是IStringLocalizer 的泛型版本
  • StringLocalizer<TResourceSource>,该类是IStringLocalizer<T> 的实现类,内部分装IStringLocalizer 接口。使用了代理模式(前面我们介绍的配置文件、以及依赖注入都使用了该模式),所有方法都是内部IStringLocalizer对象的封装。该类的构造函数是IStringLocalizerFactory接口。
  • IStringLocalizerFactory接口:根据不同的Type类型创建不同的IStringLocalizer对象
public struct LocalizedString    {        public LocalizedString([NotNull] string name, [NotNull] string value)            : this(name, value, resourceNotFound: false)        {        }        public LocalizedString([NotNull] string name, [NotNull] string value, bool resourceNotFound)        {            Name = name;            Value = value;            ResourceNotFound = resourceNotFound;        }        public static implicit Operator string (LocalizedString localizedString)        {            return localizedString.Value;        }        public string Name { get; }        public string Value { get; }        public bool ResourceNotFound { get; }        public override string ToString() => Value;    }
LocalizedString
    public interface IStringLocalizer : IEnumerable<LocalizedString>    {        LocalizedString this[string name] { get; }        LocalizedString this[string name, params object[] arguments] { get; }                IStringLocalizer WithCulture(CultureInfo culture);    }
IStringLocalizer
public interface IStringLocalizer<T> : IStringLocalizer    {    }public class StringLocalizer<TResourceSource> : IStringLocalizer<TResourceSource>    {        PRivate IStringLocalizer _localizer;        public StringLocalizer([NotNull] IStringLocalizerFactory factory)        {            _localizer = factory.Create(typeof(TResourceSource));        }        public virtual IStringLocalizer WithCulture(CultureInfo culture) => _localizer.WithCulture(culture);        public virtual LocalizedString this[[NotNull] string name] => _localizer[name];        public virtual LocalizedString this[[NotNull] string name, params object[] arguments] =>            _localizer[name, arguments];        public virtual LocalizedString GetString([NotNull] string name) => _localizer.GetString(name);        public virtual LocalizedString GetString([NotNull] string name, params object[] arguments) =>            _localizer.GetString(name, arguments);        public IEnumerator<LocalizedString> GetEnumerator() => _localizer.GetEnumerator();        IEnumerator IEnumerable.GetEnumerator() => _localizer.GetEnumerator();    }
StringLocalizer

根据上面的介绍,我们可以推断该类库的使用方式如下:

public void Test(){           IStringLocalizerFactory factory=new ResourceManagerStringLocalizerFactory();       IStringLocalizer localizer=new StringLocalizer<TType>(factory);       //IStringLocalizer<TType> localizer=new StringLocalizer<TType>();       //localizer=localizer.WithCulture(CultureInfo.CurrentUICulture);       var localizedString=localizer.GetString(key);}

[StringLocalizer<TResource>的作用就是隐藏具体IStringLocalizer,使我们不用关心是哪个IStringLocalizer,这样做对于直接书写代码可能看不出直接意义,但是如果使用依赖注入,则可以明显的看出好处,我们可以为IStringLocalizer<TType>直接注入StringLocalizer<TType>类]

[如果对于依赖注入了解不多,可以看下篇博客:DependencyInjection项目代码分析-目录,略长]

Microsoft.Framework.Localization

  • ResourceManagerStringLocalizerFactory:创建ResourceManagerStringLocalizer类资源
  • ResourceManagerStringLocalizer:resx多语言文件的访问器(实际该代码并未另起灶炉,而是使用了ResourceManager类)
  • ResourceManagerWithCultureStringLocalizer:ResourceManagerStringLocalizer的子类,提供多语言访问接口。该类实际上是在父类中WithCulture中创建,而该方法内实际也是一个类似于代理模式的设计
  • LocalizationServiceCollectionExtensions类:该类将ResourceManagerStringLocalizerFactory注入到IStringLocalizerFactory接口,StringLocalizer<T> 注入到IStringLocalizer<T> 接口。
public class ResourceManagerStringLocalizerFactory : IStringLocalizerFactory    {        private readonly IapplicationEnvironment _applicationEnvironment;        public ResourceManagerStringLocalizerFactory([NotNull] IApplicationEnvironment applicationEnvironment)        {            _applicationEnvironment = applicationEnvironment;        }        public IStringLocalizer Create([NotNull] Type resourceSource)        {            var typeInfo = resourceSource.GetTypeInfo();            var assembly = new AssemblyWrapper(typeInfo.Assembly);            var baseName = typeInfo.FullName;            return new ResourceManagerStringLocalizer(new ResourceManager(resourceSource), assembly, baseName);        }        public IStringLocalizer Create([NotNull] string baseName, [NotNull] string location)        {            var assembly = Assembly.Load(new AssemblyName(location ?? _applicationEnvironment.ApplicationName));            return new ResourceManagerStringLocalizer(                new ResourceManager(baseName, assembly),                new AssemblyWrapper(assembly),                baseName);        }    }
ResourceManagerStringLocalizerFactory
public class ResourceManagerStringLocalizer : IStringLocalizer    {        private static readonly ConcurrentDictionary<string, IList<string>> _resourceNamesCache =            new ConcurrentDictionary<string, IList<string>>();        private readonly ConcurrentDictionary<string, object> _