/// <summary> /// Serialization-required constructor /// </summary> /// <param name="info">Holds the serialized object data about the exception being thrown.</param> /// <param name="context">Contains contextual information about the source or destination.</param> private LocalizedString(SerializationInfo info, StreamingContext context) { this.Inserts = (object[])info.GetValue("inserts", typeof(object[])); // The original assembly where the string came from may not exist on the client. // In such case, deserializing the entire ExchangeResourceManager would fail since we // would not be able to load the Assembly. So we'll try that now and if it fails, // too bad...we'll just use the fallback string when formatting the string. this.ResourceManager = null; this.Id = null; try { string baseName = info.GetString("baseName"); string assemblyName = info.GetString("assemblyName"); Assembly assembly = Assembly.Load(assemblyName); this.ResourceManager = ExchangeResourceManager.GetResourceManager(baseName, assembly); this.Id = info.GetString("id"); if (null == this.ResourceManager.GetString(this.Id)) // to check the resource actually exists { this.ResourceManager = null; // The resource manager we got does not contain the string we're looking for. } } catch (System.Runtime.Serialization.SerializationException) // no assembly data { // make presharp happy (does not like empty catch blocks) this.ResourceManager = null; } catch (System.IO.FileNotFoundException) // assembly not found { // make presharp happy (does not like empty catch blocks) this.ResourceManager = null; } catch (System.Resources.MissingManifestResourceException) // resource file not found { this.ResourceManager = null; } if (null == this.ResourceManager) { // Well, we don't have a resource manager so there's no point // keeping an ID around. Let's load the formatting string in the ID // and use that to format the insert parameters. this.Id = info.GetString("fallback"); } }
/// <summary> /// Creates a new instance of the structure. /// </summary> /// <param name="id">The id of the localized string.</param> /// <param name="resourceManager">Resource Manager capable of loading the string.</param> /// <param name="inserts">Strings to be inserted in the message identified by Id.</param> public LocalizedString(string id, ExchangeResourceManager resourceManager, params object[] inserts) { if (null == id) { throw new ArgumentNullException("id"); } if (null == resourceManager) { throw new ArgumentNullException("resourceManager"); } this.Id = id; this.ResourceManager = resourceManager; // If no inserts are passed, inserts is object[0] rather than null this.Inserts = ((inserts != null) && (inserts.Length > 0)) ? inserts : null; }
/// <summary> /// Returns the instance of the ExchangeResourceManager class that looks up /// resources contained in files derived from the specified root name using the given Assembly. /// <see cref="System.Resources.ResourceManager"/> /// </summary> /// <param name="baseName">The root name of the resources.</param> /// <param name="assembly">The main Assembly for the resources.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="assembly"/> is null. /// </exception> /// <returns>ExchangeResourceManager</returns> public static ExchangeResourceManager GetResourceManager(string baseName, Assembly assembly) { if (null == assembly) { throw new ArgumentNullException("assembly"); } string key = baseName + assembly.GetName().Name; lock (lockObject) { ExchangeResourceManager resourceManager = (ExchangeResourceManager)resourceManagers[key]; if (null == resourceManager) { resourceManager = new ExchangeResourceManager(baseName, assembly); resourceManagers[key] = resourceManager; } return(resourceManager); } }
/// <summary> /// Encapsulates a hardcoded formatting string and /// its parameters as a LocalizedString. /// </summary> /// <param name="format">Formatting string.</param> /// <param name="inserts">Insert parameters.</param> /// <remarks> /// The formatting string is localized "as-is". /// This is used to append strings and other things like that. /// </remarks> private LocalizedString(string format, object[] inserts) { this.Id = format; this.Inserts = inserts; this.ResourceManager = null; }
/// <summary> /// Encapsulates a string in a LocalizedString. /// </summary> /// <remarks> /// While the rule of thumb says that an implicit conversion /// can be used when there's no loss of data, this is not the case /// with this constructor. When going from string to LocalizedString /// we don't lose information but we don't gain information /// either. The usage pattern of LocalizedString asks that /// if a string is to be localizable it should always be /// transported around in a LocalizedString. If you are setting /// a LocalizedString from a string it is most likely /// that you lost data already, somewhere else. To flag this /// problem, instead of an implicit conversion we have a constructor /// to remind people that this is not your ideal situation. This way /// we can also search for "new LocalizedString" in the code and /// see where we're doing this and come up with a design where /// we will not lose the localization information until it's /// time to show the string to the user. /// Ideally, we would be able to remove all instances where we /// need this constructor, but then people would just create a /// localized string "{0}", which would give us just about the /// same thing with less perf. /// </remarks> /// <param name="value"> /// String to encapsulate. /// Note that if value is null this creates a copy of /// LocalizedString.Empty and ToString will return "", not null. /// This is intentional to avoid returning null from ToString(). /// </param> public LocalizedString(string value) { this.Id = value; this.Inserts = null; this.ResourceManager = null; }