/////////////////////////////////////////////////////////////////////// // // WARNING: Do not use this method from the GlobalConfiguration class. // public static bool TryGetEnumAppSetting( string name, /* in */ Type enumType, /* in */ string oldValue, /* in */ out object value, /* out */ ref Result error /* out */ ) { string stringValue; if (!TryGetAppSetting(name, out stringValue, ref error)) { value = null; return(false); } object enumValue = null; if (EnumOps.IsFlagsEnum(enumType)) { enumValue = Utility.TryParseFlagsEnum( null, enumType, oldValue, stringValue, null, true, true, true, ref error); } else { enumValue = Utility.TryParseEnum( enumType, stringValue, true, true, ref error); } if (!(enumValue is Enum)) { value = null; return(false); } value = enumValue; return(true); }
/////////////////////////////////////////////////////////////////////// // // HACK: This is a horrible hack to workaround the issue with not being // able to use plugin enumerated types from the "primary" // application domain when the plugin has been loaded in isolated // mode. // public static ReturnCode FixupOptions( IPluginData pluginData, OptionDictionary options, bool strict, ref Result error ) { if (pluginData == null) { if (strict) { error = "invalid plugin data"; return(ReturnCode.Error); } return(ReturnCode.Ok); } if (options == null) { if (strict) { error = "invalid options"; return(ReturnCode.Error); } return(ReturnCode.Ok); } if (!IsIsolated(pluginData)) { return(ReturnCode.Ok); } Assembly assembly = pluginData.Assembly; foreach (KeyValuePair <string, IOption> pair in options) { IOption option = pair.Value; if (option == null) { continue; } // // HACK: Skip options that do not have enumerated types. // For now, these are the only options we really have to // worry about because they are the only ones that can // directly refer to user-defined types [of any kind]. // if (!option.HasFlags(OptionFlags.MustBeEnum, true)) { continue; } // // NOTE: Grab the enumerated (?) type and figure out if it // came from the plugin assembly. If not, ignore it and // continue. // Type type = option.Type; if ((type == null) || !type.IsEnum || !Object.ReferenceEquals(type.Assembly, assembly)) { continue; } // // NOTE: Get the current value of the option. // object oldValue = option.InnerValue; TypeCode typeCode = TypeCode.Empty; // // NOTE: Attempt to get the new value for the integral type for // the enumeration value of this option, if any. We must // do this even if the original value is null because we // must have the type code to properly reset the option // flags. // object newValue = EnumOps.ConvertToTypeCodeValue( type, (oldValue != null) ? oldValue : 0, ref typeCode, ref error); if (newValue == null) { return(ReturnCode.Error); } // // NOTE: Get the option flags required for the integral type. // OptionFlags flags = GetEnumOptionFlags(typeCode, strict); if (flags == OptionFlags.None) { error = String.Format( "unsupported type code for enumerated type \"{0}\"", type); return(ReturnCode.Error); } // // NOTE: Special handling for "flags" enumerations here. // if (EnumOps.IsFlagsEnum(type)) { // // HACK: Substitute our placeholder flags enumerated type. // It does not know about the textual values provided // by the actual enumerated type; however, at least // they can use the custom flags enumeration handling // (i.e. the "+" and "-" operators, etc). // option.Type = typeof(StubFlagsEnum); } else { // // NOTE: Remove the MustBeEnum flag for this option and add // the flag(s) needed for its integral type. // option.Flags &= ~OptionFlags.MustBeEnum; option.Flags |= flags; // // NOTE: Clear the type for the option. The type property // is only meaningful for enumeration-based options // and we are converting this option to use some kind // of integral type. // option.Type = null; } // // NOTE: If necessary, set the new [default] value for this // option to the one we converted to an integral type // value above. If the old (original) value was null, we // just discard the new value which will be zero anyhow. // option.Value = (oldValue != null) ? new Variant(newValue) : null; } return(ReturnCode.Ok); }