बड़ी .NET परियोजना में बहु-भाषा / वैश्वीकरण को लागू करने का सबसे अच्छा तरीका


86

मैं जल्द ही एक बड़े c # प्रोजेक्ट पर काम करूंगा और शुरू से ही बहु-भाषा समर्थन में निर्माण करना चाहूंगा। मेरे पास एक नाटक है और प्रत्येक भाषा के लिए एक अलग संसाधन फ़ाइल का उपयोग करके इसे प्राप्त कर सकते हैं, फिर स्ट्रिंग्स को लोड करने के लिए एक संसाधन प्रबंधक का उपयोग करें।

क्या कोई और अच्छा तरीका है जिसे मैं देख सकता हूं?

जवाबों:


88

संसाधनों के साथ एक अलग परियोजना का उपयोग करें

मैं इसे बाहर के अनुभव से बता सकता हूं, जिसमें 12 24 परियोजनाओं के साथ एक वर्तमान समाधान है जिसमें एपीआई, एमवीसी, प्रोजेक्ट लाइब्रेरी (कोर फंक्शनालिटीज), डब्ल्यूपीएफ, यूडब्ल्यूपी और एक्समरीन शामिल हैं। यह इस लंबे पोस्ट को पढ़ने के लायक है क्योंकि मुझे लगता है कि यह ऐसा करने का सबसे अच्छा तरीका है। वी.एस. उपकरणों की सहायता से अनुवाद एजेंसियों को भेजे जाने या अन्य लोगों द्वारा समीक्षा करने के लिए आसानी से निर्यात योग्य और आयात योग्य है।

EDIT 02/2018: फिर भी मजबूत होता जा रहा है, इसे एक .NET मानक लाइब्रेरी में परिवर्तित करने से यह .NET फ्रेमवर्क और NET कोर में भी उपयोग करना संभव बनाता है। मैंने इसे JSON में बदलने के लिए एक अतिरिक्त अनुभाग जोड़ा ताकि उदाहरण के लिए कोणीय इसका उपयोग कर सके।

EDIT 2019: ज़मारिन के साथ आगे बढ़ते हुए, यह अभी भी सभी प्लेटफार्मों पर काम करता है। उदाहरण के लिए Xamarin.Forms रेसक्स फ़ाइलों का उपयोग करने की सलाह देता है। (मैंने Xamarin.Forms में अभी तक एक ऐप विकसित नहीं किया है, लेकिन प्रलेखन, जो कि सिर्फ आरंभ करने के लिए विस्तृत करने का तरीका है, इसे कवर करता है: Xamarin.Forms प्रलेखन )। जेन्सन में परिवर्तित करने की तरह ही हम इसे Xamarin.Android के लिए एक .xml फ़ाइल में भी बदल सकते हैं।

EDIT 2019 (2): WPF से UWP में अपग्रेड करते समय, मैंने पाया कि UWP में वे एक और फिलामेंट का उपयोग करना पसंद करते हैं .resw, जो कंटेंट समान के संदर्भ में है लेकिन उपयोग अलग है। मुझे ऐसा करने का एक अलग तरीका मिला, जो मेरी राय में, बेहतर है तो डिफ़ॉल्ट समाधान

EDIT 2020: बड़े (modulair) परियोजनाओं के लिए कुछ सुझाव अपडेट किए गए जिनके लिए कई भाषा परियोजनाओं की आवश्यकता हो सकती है।

तो, यह करने के लिए मिलता है।

प्रो की

  • लगभग हर जगह ज़ोरदार टाइप किया गया।
  • WPF में आपको डील नहीं करनी है ResourceDirectories
  • जहाँ तक मैंने परीक्षण किया है, ASP.NET, कक्षा पुस्तकालयों, WPF, Xamarin, .NET Core, .NET मानक के लिए समर्थित है।
  • किसी अतिरिक्त तृतीय-पक्ष लाइब्रेरी की आवश्यकता नहीं है।
  • संस्कृति का समर्थन करता है: एन-यूएस -> एन।
  • बैक-एंड ही नहीं, MAM के लिए WPF और Xamarin.Forms, .cshtml के लिए XAML में भी काम करता है।
  • आसानी से बदलकर भाषा में हेरफेर करें Thread.CurrentThread.CurrentCulture
  • खोज इंजन विभिन्न भाषाओं में क्रॉल कर सकते हैं और उपयोगकर्ता भाषा-विशिष्ट यूआरएल भेज या बचा सकते हैं।

कोन के

  • WPF XAML कभी-कभी छोटी गाड़ी है, नए जोड़े गए तार सीधे दिखाई नहीं देते हैं। पुनर्निर्माण अस्थायी फिक्स (vs2015) है।
  • UWP XAML इंटेलीजेंस सुझाव नहीं दिखाता है और डिजाइन करते समय पाठ नहीं दिखाता है।
  • मुझे बताओ।

सेट अप

अपने समाधान में भाषा परियोजना बनाएं, इसे MyProject.Language जैसा नाम दें । इसमें एक फ़ोल्डर जोड़ें जिसे संसाधन कहा जाता है, और उस फ़ोल्डर में, दो संसाधन फ़ाइलें (.resx) बनाएं। एक ने Resources.resx और दूसरे ने Resources.en.resx (या .en-GB.resx को विशिष्ट) कहा। मेरे कार्यान्वयन में, मेरे पास डिफ़ॉल्ट भाषा के रूप में एनएल (डच) भाषा है, इसलिए यह मेरी पहली फ़ाइल में जाती है, और अंग्रेजी मेरी दूसरी फ़ाइल में जाती है।

सेटअप इस तरह दिखना चाहिए:

भाषा सेटअप परियोजना

Resources.resx के लिए गुण होना चाहिए: गुण

सुनिश्चित करें कि कस्टम टूल नेमस्पेस आपके प्रोजेक्ट नेमस्पेस पर सेट है। इसका कारण यह है कि WPF में, आप ResourcesXAML के अंदर संदर्भ नहीं दे सकते ।

और संसाधन फ़ाइल के अंदर, सार्वजनिक के लिए पहुँच संशोधक सेट करें:

पहुँच संशोधक

यदि आपके पास इतना बड़ा आवेदन है (मान लीजिए कि विभिन्न मॉड्यूल हैं) तो आप ऊपर की तरह कई प्रोजेक्ट बनाने पर विचार कर सकते हैं। उस स्थिति में आप अपनी कुंजी और संसाधन वर्गों को विशेष मॉड्यूल के साथ उपसर्ग कर सकते हैं। विजुअल स्टूडियो के लिए एक ही अवलोकन में सभी फाइलों को संयोजित करने के लिए सबसे अच्छे भाषा संपादक का उपयोग करें ।

किसी अन्य प्रोजेक्ट में उपयोग कर रहा है

अपनी परियोजना का संदर्भ: संदर्भ पर राइट क्लिक करें -> संदर्भ जोड़ें -> विषय / समाधान।

किसी फ़ाइल में नाम स्थान का उपयोग करें: using MyProject.Language;

बैक-एंड में इसका उपयोग करें: string someText = Resources.orderGeneralError; यदि संसाधन नामक कुछ और है, तो बस पूरे नामस्थान में डाल दें।

MVC में उपयोग करना

MVC में आप हालांकि आप भाषा सेट करना पसंद कर सकते हैं, लेकिन मैंने यूआरएल के पैरामीटर का इस्तेमाल किया है, जिसे इस तरह सेटअप किया जा सकता है:

अन्य मानचित्रणों के नीचे मार्गकॉन्फ़िग.क्स

routes.MapRoute(
    name: "Locolized",
    url: "{lang}/{controller}/{action}/{id}",
    constraints: new { lang = @"(\w{2})|(\w{2}-\w{2})" },   // en or en-US
    defaults: new { controller = "shop", action = "index", id = UrlParameter.Optional }
);

FilterConfig.cs (, जोड़े जाने के लिए अगर ऐसा है, को जोड़ने की जरूरत हो सकती FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);करने Application_start()में विधिGlobal.asax

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new ErrorHandler.AiHandleErrorAttribute());
        //filters.Add(new HandleErrorAttribute());
        filters.Add(new LocalizationAttribute("nl-NL"), 0);
    }
}

LocalizationAttribute

public class LocalizationAttribute : ActionFilterAttribute
{
    private string _DefaultLanguage = "nl-NL";
    private string[] allowedLanguages = { "nl", "en" };

    public LocalizationAttribute(string defaultLanguage)
    {
        _DefaultLanguage = defaultLanguage;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string lang = (string) filterContext.RouteData.Values["lang"] ?? _DefaultLanguage;
        LanguageHelper.SetLanguage(lang);
    }
}

LanguageHelper सिर्फ संस्कृति जानकारी सेट करता है।

//fixed number and date format for now, this can be improved.
public static void SetLanguage(LanguageEnum language)
{
    string lang = "";
    switch (language)
    {
        case LanguageEnum.NL:
            lang = "nl-NL";
            break;
        case LanguageEnum.EN:
            lang = "en-GB";
            break;
        case LanguageEnum.DE:
            lang = "de-DE";
            break;
    }
    try
    {
        NumberFormatInfo numberInfo = CultureInfo.CreateSpecificCulture("nl-NL").NumberFormat;
        CultureInfo info = new CultureInfo(lang);
        info.NumberFormat = numberInfo;
        //later, we will if-else the language here
        info.DateTimeFormat.DateSeparator = "/";
        info.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
        Thread.CurrentThread.CurrentUICulture = info;
        Thread.CurrentThread.CurrentCulture = info;
    }
    catch (Exception)
    {

    }
}

.Cshtml में उपयोग करें

@using MyProject.Language;
<h3>@Resources.w_home_header</h3>

या यदि आप usings को परिभाषित नहीं करना चाहते हैं, तो बस पूरे नामस्थान में भरें या आप नीचे दिए गए नामस्थान को /Views/web.config में परिभाषित कर सकते हैं:

<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
  <namespaces>
    ...
    <add namespace="MyProject.Language" />
  </namespaces>
</pages>
</system.web.webPages.razor>

यह mvc कार्यान्वयन स्रोत ट्यूटोरियल: बहुत बढ़िया ट्यूटोरियल ब्लॉग

मॉडल के लिए कक्षा पुस्तकालयों में उपयोग करना

बैक-एंड का उपयोग करना समान है, लेकिन विशेषताओं में उपयोग करने के लिए सिर्फ एक उदाहरण है

using MyProject.Language;
namespace MyProject.Core.Models
{
    public class RegisterViewModel
    {
        [Required(ErrorMessageResourceName = "accountEmailRequired", ErrorMessageResourceType = typeof(Resources))]
        [EmailAddress]
        [Display(Name = "Email")]
        public string Email { get; set; }
    }
}

यदि आपके पास फेरबदल है तो यह स्वचालित रूप से जांच करेगा कि क्या दिए गए संसाधन का नाम मौजूद है। यदि आप टाइप सेफ्टी पसंद करते हैं तो आप एनम उत्पन्न करने के लिए T4 टेम्प्लेट का उपयोग कर सकते हैं

WPF में उपयोग करना।

Ofcourse अपने MyProject.Language नाम स्थान का संदर्भ जोड़ें , हम जानते हैं कि इसे बैक-एंड में कैसे उपयोग किया जाए।

XAML में, किसी विंडो या UserControl के हेडर के अंदर, एक नेमस्पेस रेफरेंस जोड़ें langजैसे कि:

<UserControl x:Class="Babywatcher.App.Windows.Views.LoginView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:MyProject.App.Windows.Views"
              xmlns:lang="clr-namespace:MyProject.Language;assembly=MyProject.Language" <!--this one-->
             mc:Ignorable="d" 
            d:DesignHeight="210" d:DesignWidth="300">

फिर, एक लेबल के अंदर:

    <Label x:Name="lblHeader" Content="{x:Static lang:Resources.w_home_header}" TextBlock.FontSize="20" HorizontalAlignment="Center"/>

चूंकि यह दृढ़ता से टाइप किया गया है आप सुनिश्चित हैं कि संसाधन स्ट्रिंग मौजूद है। सेटअप के दौरान आपको कभी-कभी परियोजना को फिर से शुरू करने की आवश्यकता हो सकती है, WPF कभी-कभी नए नामस्थानों के साथ छोटी गाड़ी है।

WPF के लिए एक और बात, भाषा को अंदर सेट करें App.xaml.cs। आप अपना स्वयं का कार्यान्वयन (स्थापना के दौरान चुनें) कर सकते हैं या सिस्टम को निर्णय लेने दे सकते हैं।

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        SetLanguageDictionary();
    }

    private void SetLanguageDictionary()
    {
        switch (Thread.CurrentThread.CurrentCulture.ToString())
        {
            case "nl-NL":
                MyProject.Language.Resources.Culture = new System.Globalization.CultureInfo("nl-NL");
                break;
            case "en-GB":
                MyProject.Language.Resources.Culture = new System.Globalization.CultureInfo("en-GB");
                break;
            default://default english because there can be so many different system language, we rather fallback on english in this case.
                MyProject.Language.Resources.Culture = new System.Globalization.CultureInfo("en-GB");
                break;
        }
       
    }
}

UWP में उपयोग करना

UWP में, Microsoft इस समाधान का उपयोग करता है , जिसका अर्थ है कि आपको नई संसाधन फ़ाइलें बनाने की आवश्यकता होगी। साथ ही आप पाठ का फिर से उपयोग नहीं कर सकते क्योंकि वे चाहते हैं कि आप x:Uidअपने नियंत्रण को XAML में अपने संसाधनों की कुंजी में सेट करें। और अपने संसाधनों में आपको Example.Textएक TextBlockपाठ को भरने के लिए करना होगा । मुझे वह समाधान बिल्कुल पसंद नहीं आया क्योंकि मैं अपने संसाधन फ़ाइलों का फिर से उपयोग करना चाहता हूं। आखिरकार मैं निम्नलिखित समाधान के साथ आया। मुझे आज ही यह पता चला (2019-09-26) इसलिए मैं कुछ और लेकर वापस आ सकता हूं अगर यह पता चले कि यह वांछित नहीं है।

इसे अपने प्रोजेक्ट में जोड़ें:

using Windows.UI.Xaml.Resources;

public class MyXamlResourceLoader : CustomXamlResourceLoader
{
    protected override object GetResource(string resourceId, string objectType, string propertyName, string propertyType)
    {
        return MyProject.Language.Resources.ResourceManager.GetString(resourceId);
    }
}

इसे App.xaml.csकंस्ट्रक्टर में जोड़ें :

CustomXamlResourceLoader.Current = new MyXamlResourceLoader();

आप कभी भी अपने एप्लिकेशन में कहां चाहते हैं, इसका उपयोग भाषा बदलने के लिए करें:

ApplicationLanguages.PrimaryLanguageOverride = "nl";
Frame.Navigate(this.GetType());

UI को रीफ़्रेश करने के लिए अंतिम पंक्ति की आवश्यकता होती है। जब मैं अभी भी इस परियोजना पर काम कर रहा हूं तो मैंने देखा कि मुझे 2 बार ऐसा करने की आवश्यकता थी। पहली बार उपयोगकर्ता द्वारा शुरू किए जाने पर मैं एक भाषा चयन के साथ समाप्त हो सकता हूं। लेकिन चूंकि यह विंडोज स्टोर के माध्यम से वितरित किया जाएगा, इसलिए भाषा आमतौर पर सिस्टम भाषा के बराबर होती है।

फिर XAML में उपयोग करें:

<TextBlock Text="{CustomResource ExampleResourceKey}"></TextBlock>

इसका उपयोग कोणीय में (JSON में कनवर्ट करें)

अब दिनों में घटकों के साथ संयोजन में कोणीय की तरह एक फ्रेम होना अधिक आम है, इसलिए बिना cshtml के। अनुवाद को जोंस फाइलों में संग्रहित किया जाता है, मैं उस कार्य को कवर नहीं करने जा रहा हूं, मैं कोणीय बहु-अनुवाद के बजाय केवल एनएक्सएक्स-अनुवाद की सिफारिश करूंगा । इसलिए यदि आप अनुवादों को JSON फ़ाइल में बदलना चाहते हैं, तो यह बहुत आसान है, मैं एक T4 टेम्पलेट स्क्रिप्ट का उपयोग करता हूं जो संसाधन फ़ाइल को json फ़ाइल में परिवर्तित करता है। मैं सिंटैक्स को पढ़ने और इसे सही ढंग से उपयोग करने के लिए टी 4 संपादक स्थापित करने की सलाह देता हूं क्योंकि आपको कुछ संशोधन करने की आवश्यकता है।

केवल 1 बात पर ध्यान दें: डेटा उत्पन्न करना, उसकी प्रतिलिपि बनाना, डेटा साफ़ करना और दूसरी भाषा के लिए उत्पन्न करना संभव नहीं है। इसलिए आपको कोड के नीचे कई बार जितनी भाषाएं हैं उतनी बार कॉपी करना होगा और '// भाषा चुनें' से पहले प्रविष्टि बदलनी होगी। वर्तमान में इसे ठीक करने का कोई समय नहीं है, लेकिन संभवत: बाद में अपडेट करेगा (यदि रुचि है)।

पथ: MyProject.Language / T4 / CreateLocalizationEN.tt

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Windows.Forms" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Resources" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.ComponentModel.Design" #>
<#@ output extension=".json" #>
<#


var fileNameNl = "../Resources/Resources.resx";
var fileNameEn = "../Resources/Resources.en.resx";
var fileNameDe = "../Resources/Resources.de.resx";
var fileNameTr = "../Resources/Resources.tr.resx";

var fileResultName = "../T4/CreateLocalizationEN.json";//choose language here
var fileResultPath = Path.Combine(Path.GetDirectoryName(this.Host.ResolvePath("")), "MyProject.Language", fileResultName);
//var fileDestinationPath = "../../MyProject.Web/ClientApp/app/i18n/";

var fileNameDestNl = "nl.json";
var fileNameDestEn = "en.json";
var fileNameDestDe = "de.json";
var fileNameDestTr = "tr.json";

var pathBaseDestination = Directory.GetParent(Directory.GetParent(this.Host.ResolvePath("")).ToString()).ToString();

string[] fileNamesResx = new string[] {fileNameEn }; //choose language here
string[] fileNamesDest = new string[] {fileNameDestEn }; //choose language here

for(int x = 0; x < fileNamesResx.Length; x++)
{
    var currentFileNameResx = fileNamesResx[x];
    var currentFileNameDest = fileNamesDest[x];
    var currentPathResx = Path.Combine(Path.GetDirectoryName(this.Host.ResolvePath("")), "MyProject.Language", currentFileNameResx);
    var currentPathDest =pathBaseDestination + "/MyProject.Web/ClientApp/app/i18n/" + currentFileNameDest;
    using(var reader = new ResXResourceReader(currentPathResx))
    {
        reader.UseResXDataNodes = true;
#>
        {
<#
            foreach(DictionaryEntry entry in reader)
            {
                var name = entry.Key;
                var node = (ResXDataNode)entry.Value;
                var value = node.GetValue((ITypeResolutionService) null); 
                 if (!String.IsNullOrEmpty(value.ToString())) value = value.ToString().Replace("\n", "");
                 if (!String.IsNullOrEmpty(value.ToString())) value = value.ToString().Replace("\r", "");
#>
            "<#=name#>": "<#=value#>",
<#

    
            }
#>
        "WEBSHOP_LASTELEMENT": "just ignore this, for testing purpose"
        }
<#
    }
    File.Copy(fileResultPath, currentPathDest, true);
}


#>

यदि आपके पास एक मोड्यूलर एप्लिकेशन है और आपने कई भाषा परियोजनाओं को बनाने के लिए मेरे सुझाव का पालन किया है, तो आपको उनमें से प्रत्येक के लिए एक टी 4 फ़ाइल बनानी होगी। सुनिश्चित करें कि json फाइलें तार्किक रूप से परिभाषित हैं, यह होना जरूरी नहीं है en.json, यह भी हो सकता है example-en.jsonएनजीएक्स-अनुवाद के साथ उपयोग करने के लिए कई जोंस फ़ाइलों को संयोजित करने के लिए , यहां दिए गए निर्देशों का पालन करें

Xamarin.Android में उपयोग करें

जैसा कि अपडेट में ऊपर बताया गया है, मैं उसी विधि का उपयोग करता हूं जैसा मैंने Angular / JSON के साथ किया है। लेकिन एंड्रॉइड एक्सएमएल फाइलों का उपयोग करता है, इसलिए मैंने एक टी 4 फाइल लिखी जो उन एक्सएमएल फाइलों को उत्पन्न करती है।

पथ: MyProject.Language / T4 / CreateAppLocalizationEN.tt

#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Windows.Forms" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Resources" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.ComponentModel.Design" #>
<#@ output extension=".xml" #>
<#
var fileName = "../Resources/Resources.en.resx";
var fileResultName = "../T4/CreateAppLocalizationEN.xml";
var fileResultRexPath = Path.Combine(Path.GetDirectoryName(this.Host.ResolvePath("")), "MyProject.Language", fileName);
var fileResultPath = Path.Combine(Path.GetDirectoryName(this.Host.ResolvePath("")), "MyProject.Language", fileResultName);

    var fileNameDest = "strings.xml";

    var pathBaseDestination = Directory.GetParent(Directory.GetParent(this.Host.ResolvePath("")).ToString()).ToString();

    var currentPathDest =pathBaseDestination + "/MyProject.App.AndroidApp/Resources/values-en/" + fileNameDest;

    using(var reader = new ResXResourceReader(fileResultRexPath))
    {
        reader.UseResXDataNodes = true;
        #>
        <resources>
        <#

                foreach(DictionaryEntry entry in reader)
                {
                    var name = entry.Key;
                    //if(!name.ToString().Contains("WEBSHOP_") && !name.ToString().Contains("DASHBOARD_"))//only include keys with these prefixes, or the country ones.
                    //{
                    //  if(name.ToString().Length != 2)
                    //  {
                    //      continue;
                    //  }
                    //}
                    var node = (ResXDataNode)entry.Value;
                    var value = node.GetValue((ITypeResolutionService) null); 
                     if (!String.IsNullOrEmpty(value.ToString())) value = value.ToString().Replace("\n", "");
                     if (!String.IsNullOrEmpty(value.ToString())) value = value.ToString().Replace("\r", "");
                     if (!String.IsNullOrEmpty(value.ToString())) value = value.ToString().Replace("&", "&amp;");
                     if (!String.IsNullOrEmpty(value.ToString())) value = value.ToString().Replace("<<", "");
                     //if (!String.IsNullOrEmpty(value.ToString())) value = value.ToString().Replace("'", "\'");
#>
              <string name="<#=name#>">"<#=value#>"</string>
<#      
                }
#>
            <string name="WEBSHOP_LASTELEMENT">just ignore this</string>
<#
        #>
        </resources>
        <#
        File.Copy(fileResultPath, currentPathDest, true);
    }

#>

एंड्रॉइड values-xxफ़ोल्डर्स के साथ काम करता है , इसलिए ऊपर values-enफ़ोल्डर में अंग्रेजी के लिए है । लेकिन आपको एक डिफ़ॉल्ट भी उत्पन्न करना होगा जो valuesफ़ोल्डर में जाता है । बस T4 टेम्पलेट के ऊपर कॉपी करें और उपरोक्त कोड में फ़ोल्डर बदलें।

वहां आप जाते हैं, अब आप अपनी सभी परियोजनाओं के लिए एक एकल संसाधन फ़ाइल का उपयोग कर सकते हैं। यह एक excl दस्तावेज़ को सब कुछ निर्यात करना बहुत आसान बनाता है और किसी को इसका अनुवाद करने और इसे फिर से आयात करने देता है।

इस अद्भुत वीएस एक्सटेंशन के लिए विशेष धन्यवाद जो resxफाइलों के साथ कमाल का काम करता है । अपने भयानक काम के लिए उसे दान देने पर विचार करें (मुझे इससे कोई लेना-देना नहीं है, मैं सिर्फ विस्तार से प्यार करता हूं)।


1. आप तैनाती के बाद और अधिक भाषाएँ कैसे जोड़ते हैं ?, Mylanguage और recompile में अधिक संसाधन जोड़कर और फिर redeploy? (२) क्या आपके पास अनुवाद के लिए कोई आईडीई या टूल है (मेरे पास ४० से अधिक फॉर्म हैं), क्या आप साझा कर सकते हैं? (३) मैंने इसे आज़माया और जब मैंने अरबी में संस्कृति बदली तो इसका अनुवाद नहीं हुआ, मैं एक प्रश्न
स्मिथ

5
1: बस dublicate Resources.xx.resx और xx को बदलें और हर जगह जहां मेरे पास स्विच स्टेटमेंट हैं भाषा जोड़ें। 2 I का उपयोग करें ResxManager (TomEnglert द्वारा) एक्सटेंशन, टूल्स के माध्यम से स्थापित किया जा सकता है -> एक्सटेंशन, भाषाओं को एक दूसरे के बगल में रखने का अच्छा तरीका लेकिन वास्तविक अनुवाद किसी और द्वारा किया जाता है (Res निर्यात प्रबंधक के साथ एक्सेल से / आसान निर्यात और आयात)। 3. इस अंतिम बार एनकाउंटर करने के साथ-साथ एक को जोड़कर, ऊपर सूचीबद्ध सभी फ़ाइलों की जांच करें, लेकिन कुछ ब्रेकप्वाइंट। हालांकि मैं WinForms में इसका इस्तेमाल नहीं किया।
CularBytes

13
क्या मैं अपना जवाब खुद दे सकता हूं? मैं सिर्फ मूर्खता से अपने खुद के जवाब की जांच करने के WPF में -.- भाषाओं के बीच स्विच करने के लिए एक बग को ठीक करने के लिए किया था
CularBytes

1
@TiagoBrenck हाय, केवल इस विशिष्ट स्थिति में, यदि अंग्रेजी आपकी डिफ़ॉल्ट भाषा है, तो आप एक resource.en-gb.resx फ़ाइल बना सकते हैं और उसमें 1% परिवर्तन जोड़ सकते हैं। डिफ़ॉल्ट रूप से, यदि भाषा en-gb का चयन किया जाता है और शब्दों का अनुवाद नहीं किया जाता है, तो यह डिफ़ॉल्ट भाषा (resource.resx) का उपयोग करता है।
CularBytes

1
आपने संसाधन फ़ाइल की कुंजियों को कैसे संरचित किया है? चूंकि मैं देखता हूं कि आप केवल एक संसाधन फ़ाइल का उपयोग करते हैं, और आपके अनुसार, आपके पास एक बहुत बड़ा ऐप है, आपने चाबियों को कैसे विभाजित किया है? "Feature.MyMessage", या "Area.Feature.MyMessage" जैसे कुछ
Francesco Venturini

21

मैंने कई अलग-अलग दृष्टिकोणों का उपयोग करके कार्यान्वित परियोजनाओं को देखा है, प्रत्येक में उनकी खूबियां और कमियां हैं।

  • एक ने इसे कॉन्फिग फाइल (मेरे पसंदीदा नहीं) में किया था
  • एक डेटाबेस का उपयोग करके किया - यह बहुत अच्छी तरह से काम किया, लेकिन आप में दर्द था पता है कि क्या बनाए रखना है।
  • एक इस्तेमाल किया गया संसाधन आपके द्वारा सुझाए जा रहे तरीके को फाइल करता है और मुझे यह कहना होगा कि यह मेरा पसंदीदा तरीका था।
  • सबसे बुनियादी एक यह स्ट्रिंग्स से भरा एक फ़ाइल का उपयोग करके किया - बदसूरत।

मैं कहूंगा कि आपके द्वारा चुनी गई संसाधन विधि बहुत मायने रखती है। अन्य लोगों के उत्तरों को देखना दिलचस्प होगा क्योंकि मुझे आश्चर्य होता है कि क्या इस तरह के काम करने का एक बेहतर तरीका है। मैंने कई संसाधनों को देखा है जो सभी संसाधन विधि का उपयोग करते हैं, जिनमें से एक एसओ पर यहीं शामिल है


5

मुझे नहीं लगता कि एक "सबसे अच्छा तरीका" है। यह वास्तव में प्रौद्योगिकियों और आपके द्वारा बनाए जा रहे अनुप्रयोग के प्रकार पर निर्भर करेगा।

Webapps डेटाबेस में जानकारी को संग्रहीत कर सकते हैं जैसा कि अन्य पोस्टरों ने सुझाव दिया है, लेकिन मैं अलग संसाधन फ़ाइलों का उपयोग करने की सलाह देता हूं। वह संसाधन फ़ाइलें आपके स्रोत से अलग होती हैं । अलग-अलग संसाधन फ़ाइलें समान फ़ाइलों के लिए विवाद को कम करती हैं और जैसे-जैसे आपकी परियोजना बढ़ती है आप पा सकते हैं कि स्थानीयकरण व्यावसायिक तर्क से अलग हो जाएगा। (प्रोग्रामर और अनुवादक)।

Microsoft WinForm और WPF गुरु प्रत्येक स्थान के लिए अनुकूलित रिसोर्स असेंबलियों का उपयोग करने की सलाह देते हैं।

WP तत्वों को आकार देने के लिए WPF की क्षमता लेआउट कार्य को कम करने की आवश्यकता है जैसे: (जापानी शब्द अंग्रेजी की तुलना में बहुत कम हैं)।

यदि आप WPF पर विचार कर रहे हैं: मेरा सुझाव है कि इस msdn लेख को पढ़ने के लिए सत्य होने के लिए मुझे WPF स्थानीयकरण उपकरण मिले: msbuild, locbaml, (और शायद एक एक्सेल स्प्रेडशीट) उपयोग करने के लिए थकाऊ, लेकिन यह काम नहीं करता है।

केवल कुछ थोड़ा संबंधित: एक आम समस्या मैं विरासत प्रणाली को एकीकृत कर रहा हूं जो त्रुटि संदेश भेजता है (आमतौर पर अंग्रेजी में), त्रुटि कोड नहीं। यह ताक़तें या तो लीगेसी सिस्टम में बदल जाती हैं, या बैकिंग स्ट्रिंग्स को मेरे स्वयं के त्रुटि कोड और फिर स्थानीयकृत स्ट्रिंग्स के लिए मैपिंग ... yech। त्रुटि कोड स्थानीयकरण मित्र हैं


4

+1 डेटाबेस

यदि डेटाबेस में सुधार किया जाता है, तो आपके ऐप में मौजूद फ़ॉर्म भी खुद को फिर से अनुवाद कर सकते हैं।

हमने एक ऐसी प्रणाली का उपयोग किया जहां भाषा नियंत्रण आईडी के लिए एक्सएमएल फ़ाइल (प्रति प्रपत्र) में सभी नियंत्रणों को मैप किया गया था, लेकिन सभी आईडी डेटाबेस में थे।

मूल रूप से, प्रत्येक नियंत्रण आईडी रखने (इंटरफ़ेस को लागू करने, या VB6 में टैग संपत्ति का उपयोग करके) रखने के बजाय, हमने इस तथ्य का उपयोग किया कि .NET में, नियंत्रण पेड़ प्रतिबिंब के माध्यम से आसानी से खोजा जा सकता था। एक प्रक्रिया जब फॉर्म लोड किया जाता है तो XML फ़ाइल का निर्माण होता है यदि यह गायब था। XML फ़ाइल उनके संसाधन ID पर नियंत्रण को मैप करेगी, इसलिए इसे डेटाबेस में भरने और मैप करने की आवश्यकता है। इसका मतलब यह है कि संकलित बाइनरी को बदलने की कोई आवश्यकता नहीं थी अगर कुछ टैग नहीं किया गया था, या यदि इसे किसी अन्य आईडी को विभाजित करने की आवश्यकता है (अंग्रेजी में कुछ शब्द जो कि संज्ञा और क्रिया दोनों के रूप में उपयोग किए जा सकते हैं, दो अलग-अलग शब्दों में अनुवाद करने की आवश्यकता हो सकती है शब्दकोश में और फिर से उपयोग नहीं किया जा सकता है, लेकिन आपको आईडी के प्रारंभिक असाइनमेंट के दौरान यह पता नहीं चल सकता है)।

केवल वही जहां ऐप अधिक जुड़ जाता है जब सम्मिलन बिंदुओं के साथ एक चरण का उपयोग किया जाता है।

डेटाबेस अनुवाद सॉफ्टवेयर आपकी मूल CRUD रखरखाव स्क्रीन थी जिसमें विभिन्न अनुवाद विकल्पों के साथ अनुपलब्ध अनुवादों के माध्यम से जाने की सुविधा थी।


मुझे आपकी विधि पसंद है, क्या आप मुझे बता सकते हैं कि xml फ़ाइल कैसे उत्पन्न होती है और फिर डेटाबेस में मैप की जाती है?
स्मिथ

Form_Load या जो भी हो, अनुवाद फ़ंक्शन को प्रपत्र उदाहरण पर लागू किया गया था। उस प्रपत्र के लिए XML फ़ाइल लोड की गई थी। यदि यह मौजूद नहीं था तो इसे बनाया गया था। मेरे पास स्कीमा ऑफ-हैंड नहीं है, लेकिन मूल रूप से, इसने नियंत्रण नाम को अनुवाद आईडी के रूप में मैप किया। तो उस फॉर्म पर कोई नियंत्रण जो XML फ़ाइल में नहीं था, उसे बिना अनुवाद आईडी के एक प्रविष्टि मिलेगी। क्योंकि वे मांग पर बनाए जाएंगे, आप बस अपना फॉर्म बना सकते हैं, ऐप को चला सकते हैं जो किसी भी लापता नियंत्रण के लिए XML फ़ाइल का निर्माण या अपडेट करेगा। फिर मदों के लिए अनुवाद आईडी भरें।
केड रूक्स

4

मैं खोज रहा हूँ और मुझे यह मिला:

यदि आपके WPF या सिल्वरलाइट का उपयोग करने से आपके aproach का कई कारणों से WPF LocalizationExtension का उपयोग किया जा सकता है।

आईटीओ ओपन सोर्स इट्स फ्री (और फ्री रहेंगे) एक वास्तविक स्टैबल अवस्था में है

विंडोज एप्लीकेशन में आप कुछ इस तरह से कर सकते हैं:

public partial class App : Application  
{  
     public App()  
     {             
     }  
 
     protected override void OnStartup(StartupEventArgs e)  
     {  
         Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("de-DE"); ;  
         Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("de-DE"); ;  
 
          FrameworkElement.LanguageProperty.OverrideMetadata(  
              typeof(FrameworkElement),  
              new FrameworkPropertyMetadata(  
                  XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));  
          base.OnStartup(e);  
    }  
} 

और मुझे लगता है कि एक Wep पेज पर aproach समान हो सकता है।

शुभ लाभ!


2

मैं कई संसाधन फ़ाइलों के साथ जाऊँगा। इसे कॉन्फ़िगर करना कठिन नहीं होना चाहिए। वास्तव में मैंने हाल ही में प्रपत्र भाषा संसाधन फ़ाइलों के साथ वैश्विक भाषा आधारित संसाधन फ़ाइलों को सेट करने पर एक समान प्रश्न का उत्तर दिया।

दृश्य स्टूडियो 2008 में स्थानीयकरण

मैं समझता हूं कि कम से कम WinForm विकास के लिए सबसे अच्छा तरीका।


संसाधनों का एक दोष यह है कि आपको भाषाओं को स्विच करने के लिए पुनरारंभ करना होगा। यह शायद अधिकांश के लिए स्वीकार्य है, लेकिन यह मेरा पालतू पेशाब है ...
रोमन स्टार्कोव

2

आप Sisulizer जैसे वाणिज्यिक टूल का उपयोग कर सकते हैं । यह प्रत्येक भाषा के लिए सैटेलाइट असेंबली बनाएगा। केवल एक चीज जिस पर आपको ध्यान देना चाहिए, वह है क्लास के नाम (यदि आप ऑब्सफ्यूलेटर का उपयोग करते हैं) को बाधित नहीं करना है।


0

अधिकांश ओपन सोर्स प्रोजेक्ट्स इस उद्देश्य के लिए गेटटेक्स्ट का उपयोग करते हैं । मैं नहीं जानता कि कैसे और अगर यह कभी भी एक .Net परियोजना पर पहले इस्तेमाल किया गया है।


0

हम बहु भाषा समर्थन के लिए एक कस्टम प्रदाता का उपयोग करते हैं और सभी ग्रंथों को एक डेटाबेस तालिका में डालते हैं। यह अच्छी तरह से काम करता है सिवाय इसके कि हम कभी-कभी वेब एप्लिकेशन को अपडेट किए बिना डेटाबेस में टेक्स्ट अपडेट करते समय कैशिंग समस्याओं का सामना करते हैं।


0

मानक संसाधन फ़ाइलें आसान हैं। हालाँकि, यदि आपके पास कोई भी भाषा आश्रित डेटा है जैसे लुकअप टेबल तो आपको दो संसाधन सेट का प्रबंधन करना होगा।

मैंने ऐसा नहीं किया है, लेकिन अपनी अगली परियोजना में मैं एक डेटाबेस संसाधन प्रदाता को लागू करूंगा। मैंने पाया कि इसे MSDN पर कैसे करें:

http://msdn.microsoft.com/en-us/library/aa905797.aspx

मुझे यह कार्यान्वयन भी मिला:

DBResource प्रदाता

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.