Yerelleştirilmiş Uygulama Kaynakları. Neden geçerli bir koda ihtiyacınız var ve doğrulama hatalarını nasıl düzeltebilirsiniz?

  • 28.04.2019

Bir kitaplık özniteliğine sahip olun. Nedir ve nasıl kullanılmalıdır? İnternette bunun gibi kullanan birçok örnek var. genel tip kullanılan etikete bağlı olarak kitaplık adı olarak içerik / dosya css, js ve img (veya resim):

Bu nasıl faydalıdır? Bu örneklerdeki kitaplık değeri, etiket adıyla zaten temsil edileni tekrar ediyor gibi görünüyor. İçin etiket adına dayanmaktadır, bunun bir "CSS kitaplığı" olduğu zaten açıktır. Aynı şekilde çalışan aşağıdakilerle arasındaki fark nedir?

Ayrıca, oluşturulan HTML çıktısı kısmen farklı. * .xhtml url modelinde görüntüleme bağlam yolu / bağlam adı ve FacesServlet verildiğinde, ilki sorgu parametresi olarak kitaplık adıyla aşağıdaki HTML'yi oluşturur:

İkincisi, yalnızca URI yolunda kitaplık adıyla aşağıdaki HTML'yi oluşturur:

İkinci yaklaşım, geriye dönük olarak, aynı zamanda daha somut hale getirir. eski yaklaşım... Kütüphane özniteliği ne kadar yararlıdır?

1 cevap

Aslında bu örneklerin tümü, genel içerik/dosya türünün "js", "css", "img" vb. olduğu İnternet üzerindedir. kütüphane adı olarak kullanılır yanıltıcı.

Gerçek dünya örnekleri

İlk olarak, Mojarra ve MyFaces gibi mevcut JSF uygulamalarının ve PrimeFaces ve OmniFaces gibi JSF bileşen kitaplıklarının bunu nasıl kullandığına bakalım. Hiçbiri kaynak kitaplıklarını bu şekilde kullanmaz. Bunu (kapakların altında veya) şöyle kullanırlar:

Bunun esas olarak bir isim olduğu anlaşılmaktadır. paylaşılan kütüphane / modül / tema tüm bu kaynakların genellikle ait olduğu yer.

Tanımlanması daha kolay

Böylece bu kaynakların nereye ait olduğunu ve/veya nereden kaynaklandığını belirtmek ve ayırt etmek çok daha kolaydır. Kendi web uygulamanızda bazı varsayılan css CSS'lerini geçersiz kıldığınız/sonlandırdığınız bir primefaces.css kaynağınız olduğunu düşünün; PrimeFaces, kendi primefaces.css dosyası için kitaplık adını kullanmıyorsa, yerel PrimeFaces yüklenmeyecek, bunun yerine web uygulaması tarafından sağlanacak ve bu da görünüm "n" hissini bozacaktır.

Ayrıca, özel bir kitaplık kullandığınızda, kitaplık doğru kullanıldığında belirli bir kitaplıktan gelen kaynaklar üzerinde daha ayrıntılı denetim de uygulayabilirsiniz. Tüm bileşen kitaplıkları tüm JS dosyaları için "js" kullandıysa, belirli bir bileşen kitaplığından geliyorsa ResourceHandler nasıl farklı olurdu? Örnekler OmniFaces ve; zincirdeki bir sonraki kaynak işleyicisine geçmeden önce kitaplığın teslim alındığı createResource() yöntemini kontrol edin. Bu şekilde, bu amaç için ne zaman bir CombinedResource veya GraphicResource oluşturulacağını bilirler.

RichFaces'in yanlış yaptığını kaydetti. Herhangi bir kitaplık kullanmadı ve üzerine başka bir kaynak işleme katmanı koydu ve bu nedenle RichFaces kaynaklarını programlı olarak tanımlamak mümkün değil. Bu nedenle OmniFaces, RichFaces varlıklarıyla yine de çalışmasını sağlamak için yansıma tabanlı korsanlığı tanıtmak zorunda kaldı.

Kendi web uygulamanız

Kendi web uygulamanızın mutlaka bir kaynak kitaplığına ihtiyacı yoktur. En iyi bahsiniz, onu atlamaktır.

Veya gerçekten sahip olmanız gerekiyorsa, ona daha akıllıca verebilirsiniz. yaygın isim, örneğin "varsayılan" veya bir şirket adı.

Veya kaynaklar bazı Masterlet şablonlarına özel olduğunda, birbirine bağlamayı kolaylaştırmak için ona bir şablon adı da verebilirsiniz. Başka bir deyişle, daha çok kendi kendini belgeleme amaçlıdır. Örneğin. /WEB-INF/templates/layout.xhtml şablon dosyasında:

Ve şablon dosyası /WEB-INF/templates/admin.xhtml:

Gerçek bir dünya örneği için, OmniFaces vitrininin kaynak kodunu kontrol edin.

Veya aynı kaynakları birden çok web klasörüne bölmek ve onlar için oluşturduysanız ortak proje bu cevaptakiyle aynı örneğe dayanarak, bu da JAR'a webapp/WEB-INF/lib'de gömülüdür ve daha sonra ona bir kitaplık olarak atıfta bulunur (seçtiğiniz ad, bu nedenle OmniFaces ve PrimeFaces gibi bileşen kitaplıkları):

Kitaplık sürüm oluşturma

Bir diğer önemli faydası ise doğru şekilde kullanabilmenizdir. doğru versiyonu kendi web uygulamanız tarafından sağlanan kaynaklardaki kaynak kitaplıkları (bu, JAR'lara gömülü kaynaklar için çalışmaz). Kaynak kitaplığının sürümünü belirtmek için \ d + (_ \ d +) * kalıbında adlandırılan kitaplık klasöründe doğrudan bir alt klasör oluşturabilirsiniz.

Web İçeriği | - kaynaklar | `- varsayılan | `- 1_0 | |-css | | `- style.css | | - görsel | | `- logo.png | `- js | `- script.js:

Bu işaretlemeyi kullanırken:

Bu oluşturacak HTML'yi takip etmek v olarak kütüphane sürümü ile:

Bu nedenle, bazı kaynakları düzenlediyseniz/güncellediyseniz, tek yapmanız gereken sürüm klasörünü yeni bir değere kopyalamak veya yeniden adlandırmaktır. Birden çok sürüm klasörünüz varsa, JSF ResourceHandler, kaynağı sayısal sıralama kurallarına göre en yüksek sürüm numarasından otomatik olarak sunacaktır.

Bu nedenle, kaynakları kopyalarken / yeniden adlandırırken / varsayılan / 1_0 / *, aşağıda gösterildiği gibi kaynaklar / varsayılan / 1_1 / * klasörüne:

Web İçeriği | - kaynaklar | `- varsayılan | | - 1_0 | | : | | | `- 1_1 | |-css | | `- style.css | | - görsel | | `- logo.png | `- js | `- script.js:

Daha sonra son örnek işaretleme aşağıdaki HTML'yi oluşturacaktır:

Bu, web tarayıcısını, değiştirilen url ilk kez istendiğinde önbellekten aynı adı göstermek yerine kaynağı doğrudan sunucudan istemeye zorlar. Böylece, son kullanıcılar güncellenmiş bir CSS / JS kaynağı almaları gerektiğinde herhangi bir donanım güncellemesi (Ctrl + F5, vb.) gerekmez.

Yerelleştirilmiş Uygulama Kaynakları

Görüntüler ve dize tabloları gibi kaynaklar, kaynak dosyalarına veya alt montajlara yerleştirilebilir. Bu kaynaklar, uygulamaları yerelleştirirken çok faydalı olabilir ve .NET, yerelleştirilmiş kaynakları bulmak için yerleşik destek sunar.

Uygulamaları yerelleştirmek için kaynakların nasıl kullanılacağına bakmadan önce, dil özelliklerini dikkate almadan kaynakların nasıl oluşturulacağına ve okunacağına bir göz atalım.

Kaynak dosyaları oluşturma

Kaynak dosyaları, görüntüler ve dize tabloları gibi öğeleri depolayabilir. Kaynak dosyası, bir düz metin dosyası veya XML kullanan bir .resX dosyası olabilir. Bu makale ilk olarak düz metin dosyası seçeneğine bakmaktadır.

Bir satır tablosu içeren bir kaynak, düzenli bir şekilde oluşturulabilir. Metin dosyası... Bu dosya sadece tuşlara dizeler atar. Anahtar, ilgili değeri almak için programda kullanılabilecek bir addır. Anahtarlarda ve değerlerde boşluklara izin verilir.

Basit bir dize tablosu oluşturma örneği aşağıda gösterilmiştir:

Başlık = Profesyonel C# Site = Site Yazarı = Alex Erohin

Resgen.exe yardımcı programı

***'den oluşturmak için. robots.txt dosyası kaynaklar kullanılabilir özel yardımcı program kaynak dosyaları oluşturma Resgen.exe. Örneğin, aşağıdaki komutu girerek:

Resgen MyResources.txt

MyResources.resources dosyasının oluşturulmasıyla sonuçlanacaktır. Bu yardımcı program tarafından oluşturulan kaynak dosyası daha sonra derlemeye şu şekilde eklenebilir: harici dosya veya derleme DLL veya EXE dosyasına ekleyin. Resgen ayrıca .resX uzantısıyla XML kaynak dosyaları oluşturma özelliğini de destekler. Çok basit bir şekilde kullanılır:

Resgen MyResources.txt MyResources.resX

Bu komutu çalıştırmak, MyResources.resX adlı bir XML kaynak dosyası oluşturacaktır.

Resgen yardımcı programı, kesinlikle yazılan kaynakları destekler. Kesin olarak yazılan bir kaynak, kaynaklara erişen bir sınıf olarak temsil edilir. Böyle bir sınıf oluşturmak için Resgen yardımcı programı / str seçeneğini sunar:

Resgen /str:C#,MyResources.cs MyResources.resX

/str seçeneğinin ardından dil, ad alanı, sınıf adı ve dosya adı gelmelidir. kaynak kodu, ve bu sırayla.

Resgen yardımcı programı, resim ekleme özelliğini desteklemez. .NET Framework SDK örnekleri, öğreticilerle birlikte ResXGen örneğini içerir. ResXGen'de, bir .resX dosyasındaki resimlere başvurabilirsiniz. Ayrıca, aşağıda gösterildiği gibi, ResourceWriter veya ResXResourceWriter sınıflarını kullanarak görüntüleri programlı olarak ekleyebilirsiniz.

ResourceWriter sınıfı

Kaynak dosyaları oluşturmak için Resgen yardımcı programını kullanmak yerine, bunu yapmak için özel bir program yazabilirsiniz. System.Resources ad alanındaki ResourceWriter sınıfı, ikili kaynak dosyaları oluşturmak için kullanılır ve ResXResourceWriter sınıfı, XML tabanlı kaynak dosyaları oluşturmak için kullanılır. Bu sınıfların her ikisi de görüntü ve diğer serileştirilebilir nesneler ekleme özelliğini destekler. ResXResourceWriter sınıfını kullanıyorsanız, System.Windows.Forms derlemesine başvurmanız gerekir.

Aşağıdaki kod örneği, Demo.resx dosyasında rw adlı bir ResXResourceWriter'ın nasıl oluşturulacağını gösterir. ResXResourceWriter'ın AddResource() yöntemini kullanarak bir instance oluşturduktan sonra toplamda 2 GB'a kadar bir kaynak seti eklemeye başlayabilirsiniz. AddResource () öğesinin ilk argümanı kaynağın adını belirtmenize, ikincisi ise değeri belirtmenize izin verir. Image sınıfının bir örneği kullanılarak bir görüntü kaynağı eklenebilir. Image sınıfını kullanmak için System.Drawing derlemesine başvurmanız ve System.Drawing ad alanını açmak için bir using yönergesi eklemeniz gerekir.

Burada, Image nesnesi logo.gif dosyası açılarak oluşturulur, bu nedenle bu görüntü dosyasını yürütülebilir programın dizinine kopyalamanız veya ImageToFile () yönteminin argümanında bunun tam yolunu belirtmeniz gerekir. using ifadesi, using bloğunun sonunda görüntü kaynağının otomatik olarak yok edilmesi gerektiğini belirtir.

Ardından, ResXResourceWriter nesnesine basit dize kaynakları eklenir. Son olarak, ResXResourceWriter sınıfının Close () yöntemi, kaynakları Demo.resx dosyasına yazmak için otomatik olarak ResXResourceWriter.Generate () öğesini çağırır:

System.Drawing'i Kullanmak; System.Resources kullanarak; ad alanı ProCSharp.Localization (sınıf Program (static void Main () (var rw = new ResXResourceWriter ("Demo.resx")); kullanarak ( Resim resmi= Image.FromFile ("logo.gif")) (rw.AddResource ("Logom", resim); rw.AddResource ("Başlık", "Profesyonel C #"); rw..AddResource ("Yazar", "Alex Erohin "); rw.Kapat ();))))

Bunu başlatmak küçük program içinde bir logo.gif resmi bulunan bir Demo.resx kaynak dosyasıyla sonuçlanacaktır.

Kaynak dosyalarını kullanma

kullanarak derlemelere kaynak dosyaları ekleyebilirsiniz. Komut satırı C # derleyici csc.exe / kaynak seçeneğiyle veya doğrudan Görsel stüdyo 2010. Visual Studio 2010'da kaynak dosyalarla nasıl çalışılacağını görmek için bir proje oluşturun konsol uygulaması adlı ResourceDemo.

Çözüm penceresinde açarak önceden oluşturulmuş Demo.resx kaynak dosyasını bu projeye ekleyin Gezgin bağlamsal menüsüne gidin ve Ekle -> Mevcut Öğeyi Ekle'yi seçin. Varsayılan olarak, bu kaynağın Eylem Oluştur özelliği, bu kaynağın çıktı derlemesine katıştırılması gerektiğini belirten Gömülü Kaynak olarak ayarlanacaktır.

Ardından, proje parametrelerinde (Uygulama -> Montaj bilgileri'ni seçerek), ana dili Neutral Language parametresinin değeri olarak ayarlayın:

Bu parametrenin değerini değiştirmek, Assemblyinfo.cs dosyasına bir öznitelik ekleyecektir. Aşağıda gösterildiği gibi:

için bir değer ayarlama bu özellik en-US için kaynakları daha hızlı bulmasına ve bunları varsayılan olarak kullanmasına izin vererek ResourceManager'ın performansını artıracaktır. Bu öznitelik, kurucuda ikinci bir parametre kullanarak varsayılan kaynağın konumunu da belirtebilir. Ana derlemede (değer MainAssembly) veya bir alt derlemede (değer Satellite) bulunması gerektiğini belirtmek için UltimateResourceFallbackLocation numaralandırmasını kullanabilirsiniz.

Projeyi oluşturduktan sonra, oluşturulan derlemeyi ildasm yardımcı programı ile görüntüleyebilir ve bildirimde .mresource özniteliğini görebilirsiniz. mresource özniteliği, derlemedeki kaynak için bir ad bildirir. mresource herkese açık olarak bildirilirse (olduğu gibi bu örnek), bu, kaynağın derlemeden dışa aktarılabileceği ve diğer derlemelerin sınıflarında kullanılabileceği anlamına gelir. .mresource özel olarak bildirilirse, kaynağın dışa aktarılamayacağı ve yalnızca bu derleme içinde kullanılabilir olduğu anlamına gelir.

Yerleşik kaynağa erişmek için System.Resources ad alanında bulunan ResourceManager sınıfı kullanılır. Bu sınıfın yapıcısına kaynakları içeren derlemenin adı argüman olarak iletilebilir.

Bu örnekte, kaynaklar yürütülebilir derlemeye gömülüdür, bu nedenle yöntemin sonucu ikinci argümanda yapıcıya iletilmelidir. Assembly.GetExecutingAssembly ()... İlk bağımsız değişken, ad alanı adı ve kaynak dosya adından oluşan, ancak kaynak uzantısı olmayan kaynağın kök adıdır. Daha önce gösterildiği gibi, bu ad ildasm yardımcı programı kullanılarak görüntülenebilir ve kaynak uzantısını buradan kaldırabilirsiniz. Adı, System.Reflection.Assembly sınıfının GetManifestResourceNames () yöntemini kullanarak programlı olarak da alabilirsiniz:

Sistemi Kullanmak; System.Drawing'i kullanarak; System.Reflection'ı kullanarak; System.Resources kullanarak; ad alanı Wrox.ProCSharp.Localization (sınıf Program (static void Main ()) (var rm = new ResourceManager ("Wrox.ProCSharp.Localization.Demo", Assembly.GetExecutingAssembly ()); Console.WriteLine (rm.GetString ("Title") )); Console.WriteLine (rm.GetString ("Site")); Console.WriteLine (rm.GetString ("Yazar")); (Resim logosu = (Görüntü) rm.GetObject ("MyLogo")) (logo) .Save ("logo.bmp");) StronglyTypedResources ();) özel statik void StronglyTypedResources () (Console.WriteLine (Demo.Title); Console.WriteLine (Demo.Site); Console.WriteLine (Demo.Author); (Bitmap logosu = Demo.MyLogo) kullanarak (logo.Save ("logo.bmp");))))

Kesinlikle yazılan bir kaynak oluşturmak için Yönetilen Kaynaklar Düzenleyicisi parametre değerini değiştirebilirsiniz Erişim Değiştirici Kodsuz Üretimden Genel veya Dahiliye. Genel olarak ayarlanırsa, oluşturulan sınıfa genel erişim değiştiricisi sağlanır ve ardından diğer derlemelerden erişilebilir. Dahili olarak ayarlandığında, oluşturulan sınıf dahili erişim değiştiricisini alır ve yalnızca içinde bulunduğu derleme içinden erişilebilir.

System.Resources ad alanı

System.Resources ad alanında bulunan ve kaynaklarla çalışmanıza izin veren tüm sınıfları hızlıca gözden geçirelim.

ResourceManager sınıfı

Derlemelerden veya kaynak dosyalarından mevcut kültürle ilgili kaynakları almak için kullanılabilir. ResourceManager ile, belirli bir kültür için tüm kaynakları bir defada bir ResourceSet örneği biçiminde alabilirsiniz.

Kaynak Kümesi sınıfı

Belirli bir kültür için bir kaynak koleksiyonunu temsil etmenize olanak tanır. Bir ResourceSet başlatıldığında, IResourceReader arabirimini uygulayarak sınıfı numaralandırır ve tüm kaynakları bir HashTable'da depolar.

IResourceReader arayüzü

Kaynakları numaralandırmak için bir ResourceSet içinde kullanılır. ResourceReader sınıfı bu arabirimi uygular.

ResourceWriter sınıfı

Bir kaynak dosyası oluşturmak için kullanılır ve IResourceWriter arabirimini uygular.

ResXResourceSet, ResXResourceReader ve ResXResourceWriter Sınıfları

ResourceSet, ResourceReader ve ResourceWriter sınıflarına benzer, ancak ikili dosya kaynaklar, bir XML .resx dosyası değil. Kaynağı bir XML dosyasına gömmek yerine, ResXFileRef kullanarak ona başvurmanıza izin verirler.

System.Resources.Tools ad alanı

Bir kaynaktan sınıf oluşturmak için kullanabileceğiniz StronglyTypedResourceBuilder sınıfını içerir.

Son güncelleme: 27.01.2016

WPF'de önemli yer kaynakları al. V bu durum kaynaklar demek değildir ek dosyalar(veya fiziksel kaynaklar), projeye eklenen ses dosyaları, görüntü dosyaları gibi. Buraya gelirÖ mantıksal kaynaklarçeşitli nesneleri temsil edebilen kontroller, fırçalar, nesne koleksiyonları vb. Mantıksal kaynaklar, Kaynaklar özelliği kullanılarak XAML veya C# içinde ayarlanabilir. Bu mülk FrameworkElement temel sınıfında tanımlanır, bu nedenle çoğu WPF sınıfında bulunur.

Kaynakları kullanmanın amacı nedir? Verimliliği artırırlar: Bir kaynağı bir kez tanımlayabilir ve ardından uygulamada farklı yerlerde yeniden kullanabiliriz. Bu bağlamda, destek iyileştirilir - kaynağı değiştirmek gerekirse, bunu tek bir yerde yapmak yeterlidir ve değişiklikler uygulamada global olarak gerçekleşecektir.

Kaynaklar özelliği, depolanan her kaynağın belirli bir anahtarına sahip olduğu bir ResourceDictionary nesnesini veya kaynak sözlüğünü temsil eder.

Kaynakları tanımlama

Pencere kaynağını ve düğme kaynağını tanımlayalım:

Burada pencere iki kaynağı tanımlar: bir SolidColorBrush nesnesini temsil eden redStyle ve doğrusal bir degrade fırçayı temsil eden gradyanStyle. Düğme, SolidColorBrush'ı temsil eden bir kaynak tanımlı, darkStyle'a sahiptir. Ayrıca, her kaynak, sözlükteki anahtarı tanımlayan x: Key özelliğine sahip olmalıdır.

Ve sırasıyla gridin ve butonun Background özelliklerinde şu kaynakları uygulayabiliriz: Background = "(StaticResource gradientStyle)" - burada, StaticResource ifadesinden sonra, uygulanan kaynağın anahtarı vardır.

C# kodunda kaynak yönetimi

Pencerenin kaynak sözlüğüne bir degrade fırçası ekleyin ve düğme için ayarlayın:

// kaynak nesnesini tanımlama LinearGradientBrush gradientBrush = new LinearGradientBrush (); gradyanBrush.GradientStops.Add (yeni GradientStop (Colors.LightGray, 0)); gradientBrush.GradientStops.Add (yeni GradientStop (Colors.White, 1)); // kaynağı this.Resources.Add penceresinin kaynak sözlüğüne ekleyin ("buttonGradientBrush", gradientBrush); // düğme kaynağının ayarlanması button1.Background = (Fırça) this.TryFindResource ("buttonGradientBrush"); // ya da öylesine //button1.Background = (Fırça) this.Resources ["buttonGradientBrush"];

Add() özelliği kullanılarak, fırça nesnesi ve onun isteğe bağlı anahtarı sözlüğe eklenir. Daha sonra TryFindResource() metodunu kullanarak sözlükte kaynağı bulmaya çalışıyoruz ve onu arka plan olarak ayarlıyoruz. Ayrıca bu metot bir nesne döndürdüğü için tiplerin dökümünü yapmak gerekir.

Toplamda, ResourceDictionary aşağıdaki yöntemlere ve özelliklere sahiptir:

    Yöntem Ekle (dize anahtarı, nesne kaynağı) ile bir nesne ekler anahtar anahtar sözlüğe ve sözlüğe herhangi bir nesne ekleyebilirsiniz, asıl şey onunla bir anahtarı ilişkilendirmektir.

    Remove (dize anahtarı) yöntemi, anahtar anahtarlı kaynağı sözlükten kaldırır

    Uri özelliği sözlüğün kaynağını belirler

    Keys özelliği, sözlükteki tüm anahtarları döndürür

    Değerler özelliği, sözlükteki tüm nesneleri döndürür

Kaynak koleksiyonunda gerekli kaynağı bulmak için her öğenin FindResource() ve TryFindResource() yöntemleri vardır. Her ikisi de belirli bir anahtara karşılık gelen bir kaynak döndürür. İkisi arasındaki tek fark, FindResource() öğesinin bir kaynak ile bir istisna oluşturmasıdır. doğru anahtar bulunamadı. Ve TryFindResource() yöntemi bu durumda basitçe null değerini döndürür.

Paylaşılan kaynaklar

Aynı kaynak kullanıldığında farklı yerler, o zaman aslında aynı nesneyi kullanıyoruz. Ancak bu her zaman arzu edilen bir durum değildir. Bazen bir kaynağın farklı nesnelere uygulanmasının farklı olması gerekir. Yani her uygulama için ayrı bir kaynak nesnesi oluşturmamız gerekiyor. Bu durumda x: Shared = "False" ifadesini kullanabiliriz:

Kaynak kullanma örnekleri

Kaynak kullanımına ilişkin birkaç örneğe daha bakalım. Örneğin, aynı özelliklere sahip birkaç düğme istiyorsak, bir tane tanımlayabiliriz. ortak düğme kaynak olarak: