/// <summary> /// Inserts a MethodCallDefinition instance into the method calls list at specified index. /// </summary> /// <param name="index">The zero-based index at which MethodCallDefinition instance should be inserted.</param> /// <param name="methodCallDefinition">The MethodCallDefinition instance to insert</param> /// <exception cref="ArgumentNullException">If the MethodCallDefinition instance to insert is null</exception> /// <exception cref="ArgumentOutOfRangeException">If index is less than zero or index is greater than Count /// of method calls list</exception> public void InsertMethodCallDefinition(int index, MethodCallDefinition methodCallDefinition) { Helper.ValidateNotNull(methodCallDefinition, "methodCallDefinition"); methodCalls.Insert(index, methodCallDefinition); }
/// <summary> /// Removes a MethodCallDefinition instance from the method calls list. /// </summary> /// <param name="methodCallDefinition">The MethodCallDefinition instance to remove</param> /// <exception cref="ArgumentNullException">If the MethodCallDefinition instance to remove is null</exception> public void RemoveMethodCallDefinition(MethodCallDefinition methodCallDefinition) { Helper.ValidateNotNull(methodCallDefinition, "methodCallDefinition"); methodCalls.Remove(methodCallDefinition); }
/// <summary> /// <p>Creates a new instance of ObjectDefinition.</p> /// </summary> /// /// <p> /// Version 1.2: Move part of parameter verification to property setter. /// </p> /// /// <param name="appDomain">The application domain (can be null or empty).</param> /// <param name="assembly">The assembly name (can be null if appDomain is null or empty).</param> /// <param name="typeName">The type name (cannot be null).</param> /// <param name="ignoreCase"> /// False for case sensitive lookup, true for case insensitive lookup of the static method name. /// </param> /// <param name="paramTypes"> /// The types of the parameters (can be null or empty). /// </param> /// <param name="paramValues"> /// The values of the parameters (can be null or empty). /// </param> /// <param name="methodCalls"> /// The method calls definitions to be made on the object after it is create (can be null). /// </param> /// <param name="instantiationLifetime"> /// InstantiationLifetime value stating the length of the lifetime of this instance. /// </param> /// <param name="methodName">The name of the static method to use to create the object.</param> /// /// <exception cref="ArgumentNullException"> /// If typeName or methodName is null or an array element (besides an element in paramValues /// corresponding to a paramType of "null") is null. /// </exception> /// <exception cref="ArgumentException"> /// If the paramTypes and paramValues arrays don't have the same size and aren't both null or /// if paramTypes has invalid values (see ParamTypes), or assembly is the empty string /// or instantiationLifetime is invalid or methodName is empty. /// </exception> /// <since>1.1</since> private ObjectDefinition(string appDomain, string assembly, string typeName, string methodName, bool ignoreCase, InstantiationLifetime instantiationLifetime, string[] paramTypes, object[] paramValues, MethodCallDefinition[] methodCalls) : base(ignoreCase, paramTypes, paramValues, methodName) { this.AppDomain = appDomain; this.Assembly = assembly; this.TypeName = typeName; this.InstantiationLifetime = instantiationLifetime; this.MethodCalls = methodCalls; }
/// <summary> /// Adds a MethodCallDefinition instance to method calls list. /// </summary> /// <returns>The position into which the new MethodCallDefinition instance was inserted.</returns> /// /// <param name="methodCallDefinition">The MethodCallDefinition instance to add</param> /// <exception cref="ArgumentNullException">If the MethodCallDefinition instance to add is null</exception> public int AddMethodCallDefinition(MethodCallDefinition methodCallDefinition) { Helper.ValidateNotNull(methodCallDefinition, "methodCallDefinition"); return methodCalls.Add(methodCallDefinition); }
/// <summary> /// <p>Creates a new instance of ObjectDefinition.</p> /// </summary> /// /// <param name="appDomain">The application domain (can be null or empty).</param> /// <param name="assembly">The assembly name (can be null if appDomain is null or empty).</param> /// <param name="typeName">The type name (cannot be null).</param> /// <param name="ignoreCase"> /// False for case sensitive lookup, true for case insensitive lookup of the static method name. /// </param> /// <param name="paramTypes"> /// The types of the parameters (can be null or empty). /// </param> /// <param name="paramValues"> /// The values of the parameters (can be null or empty). /// </param> /// <param name="methodCalls"> /// The method calls definitions to be made on the object after it is create (can be null). /// </param> /// <param name="instantiationLifetime"> /// InstantiationLifetime value stating the length of the lifetime of this instance. /// </param> /// /// <exception cref="ArgumentNullException"> /// If typeName is null or an array element (besides an element in paramValues corresponding /// to a paramType of "null") is null. /// </exception> /// <exception cref="ArgumentException"> /// If the paramTypes and paramValues arrays don't have the same size and aren't both null or /// if paramTypes has invalid values (see ParamTypes), or assembly is the empty string /// or instantiationLifetime is invalid. /// </exception> public ObjectDefinition(string appDomain, string assembly, string typeName, bool ignoreCase, string[] paramTypes, object[] paramValues, MethodCallDefinition[] methodCalls, InstantiationLifetime instantiationLifetime) : this(appDomain, assembly, typeName, null, ignoreCase, instantiationLifetime, paramTypes, paramValues, methodCalls) { isStatic = false; }
/// <summary> /// <p>Creates a new instance of ObjectDefinition.</p> /// </summary> /// /// <param name="appDomain">The application domain (can be null or empty).</param> /// <param name="assembly">The assembly name (can be null if appDomain is null or empty).</param> /// <param name="typeName">The type name (cannot be null).</param> /// <param name="ignoreCase"> /// False for case sensitive lookup, true for case insensitive lookup of the static method name. /// </param> /// <param name="paramTypes"> /// The types of the parameters (can be null or empty). /// </param> /// <param name="paramValues"> /// The values of the parameters (can be null or empty). /// </param> /// <param name="methodCalls"> /// The method calls definitions to be made on the object after it is create (can be null). /// </param> /// <param name="instantiationLifetime"> /// InstantiationLifetime value stating the length of the lifetime of this instance. /// </param> /// <param name="methodName">The name of the static method to use to create the object.</param> /// /// <exception cref="ArgumentNullException"> /// If typeName or methodName is null or an array element (besides an element in paramValues /// corresponding to a paramType of "null") is null. /// </exception> /// <exception cref="ArgumentException"> /// If the paramTypes and paramValues arrays don't have the same size and aren't both null or /// if paramTypes has invalid values (see ParamTypes), or assembly is the empty string /// or instantiationLifetime is invalid or methodName is empty. /// </exception> public ObjectDefinition(string appDomain, string assembly, string typeName, string methodName, bool ignoreCase, string[] paramTypes, object[] paramValues, MethodCallDefinition[] methodCalls, InstantiationLifetime instantiationLifetime) : this(appDomain, assembly, typeName, methodName, ignoreCase, instantiationLifetime, paramTypes, paramValues, methodCalls) { Helper.ValidateNotNull(methodName, "methodName"); isStatic = true; }
/// <summary> /// <p>Applies the given method definition to the given object.</p> /// </summary> /// /// <remarks> /// <p>This method will invoke either the method specified by the definition, /// or set the property specified by the definition.</p> /// </remarks> /// /// <param name="applyMethodsTo">The object to invoke the method on.</param> /// <param name="methodCallDefinition">The definition of the method to invoke.</param> /// /// <exception cref="MethodInvocationException">If there is an error in invoking the method.</exception> /// <exception cref="ArgumentNullException">If any argument is null.</exception> public void ApplyMethodCall(object applyMethodsTo, MethodCallDefinition methodCallDefinition) { Helper.ValidateNotNull(applyMethodsTo, "applyMethodsTo"); Helper.ValidateNotNull(methodCallDefinition, "methodCallDefinition"); try { ApplyMethodCall(applyMethodsTo, methodCallDefinition, new Hashtable(), new Hashtable()); } catch (Exception e) { throw new MethodInvocationException("Error occurred while invoking the method.", e); } }
/// <summary> /// <p>Applies the given method definition to the given object.</p> /// </summary> /// /// <remarks> /// <p>This method will invoke either the method specified by the definition, /// or set the property specified by the definition.</p> /// /// <p>Exceptions will be promulgated.</p> /// </remarks> /// /// <param name="applyMethodsTo">The object to invoke the method on.</param> /// <param name="methodCallDefinition">The definition of the method to invoke.</param> /// <param name="objectKeysSeen"> /// A set store all the keys that are waiting to be solved in the chain of recursive method calls. /// </param> /// <param name="oncePerTopLevelInstantiationObjects"> /// A dictionary store the loaded objects that are configured with OncePerTopLevelObject /// instantiation lifetime. /// </param> private void ApplyMethodCall(object applyMethodsTo, MethodCallDefinition methodCallDefinition, IDictionary objectKeysSeen, IDictionary oncePerTopLevelInstantiationObjects) { object[] parameters = GenerateActualParams( methodCallDefinition, objectKeysSeen, oncePerTopLevelInstantiationObjects); BindingFlags flags = BindingFlags.Public | BindingFlags.Instance; if (methodCallDefinition.IgnoreCase) { flags |= BindingFlags.IgnoreCase; } MethodBase[] methods; if (methodCallDefinition.IsProperty) { // since CLS allow indexed property, more than one properties may have the same name, PropertyInfo[] properties = applyMethodsTo.GetType().GetProperties(flags); // filter properties by name ArrayList candidates = new ArrayList(); foreach (PropertyInfo candidate in properties) { if (String.Compare(candidate.Name, methodCallDefinition.MethodName, methodCallDefinition.IgnoreCase) == 0) { MethodBase setter = candidate.GetSetMethod(); if (setter != null) { candidates.Add(setter); } } } methods = (MethodBase[])candidates.ToArray(typeof(MethodBase)); } else { // Get a list of methods matched the MethodName methods = FilterMethods(applyMethodsTo.GetType(), methodCallDefinition.MethodName, flags); } // select a method match the given parameters object state = null; object[] args = parameters; MethodBase method = Type.DefaultBinder.BindToMethod( flags, methods, ref args, null, null, null, out state); // invoke by the given array to insure ref/out parameters work correctly method.Invoke(applyMethodsTo, parameters); }
/// <summary> /// <para> /// Retrieves the object definition from given configuration. /// </para> /// </summary> /// /// <param name="config"> /// The configuration to read. /// </param> /// /// <returns> /// The object definition created. /// </returns> /// /// <exception cref="ConfigurationAPISourceException"> /// If exceptions occur while retrieving the definition info, but may also indicate /// incomplete definition info (missing type name), parsing errors if the source /// uses string representations or some other errors. /// </exception> private static ObjectDefinition CreateObjectDefinition(IConfiguration config) { // Read the app_domain property (optional) string appDomain = GetSimpleValueFromChild(config, ConfigAppDomain, false); // Read the assembly property (optional) string assembly = GetSimpleValueFromChild(config, ConfigAssembly, false); // Read the type_name property (required) string typeName = GetSimpleValueFromChild(config, ConfigTypeName, true); // Read the method_name property (optional) string methodName = GetSimpleValueFromChild(config, ConfigMethodName, false); // Read the ignore_case property (optional), default to false // must be a valid boolean value if exists bool ignoreCase = GetBooleanFromChild(config, ConfigIgnoreCase); // Read the instantiation_lifetime property (optional), default to Instance InstantiationLifetime instantiationLifetime = InstantiationLifetime.Instance; string instantiationLifetimeVal = GetSimpleValueFromChild(config, ConfigInstantiationLifetime, false); if (instantiationLifetimeVal != null) { instantiationLifetime = (InstantiationLifetime)Enum.Parse( typeof(InstantiationLifetime), instantiationLifetimeVal, true); } // Retrieve all values of the parameters property string[] paramTypes = null; object[] paramValues = null; GetParameters(config[ConfigParameters], ref paramTypes, ref paramValues); IConfiguration methodsConfig = config[ConfigMethods]; // Retrieve method definitions MethodCallDefinition[] methodCalls = null; if (methodsConfig != null) { int index = 0; IConfiguration[] methodConfigs = methodsConfig.Children; methodCalls = new MethodCallDefinition[methodConfigs.Length]; foreach (IConfiguration methodConfig in methodConfigs) { methodCalls[index++] = GetMethodDefinition(methodConfig); } } // construct and return an ObjectDefinition instance containing the object infomation return methodName == null ? new ObjectDefinition(appDomain, assembly, typeName, ignoreCase, paramTypes, paramValues, methodCalls, instantiationLifetime) : new ObjectDefinition(appDomain, assembly, typeName, methodName, ignoreCase, paramTypes, paramValues, methodCalls, instantiationLifetime); }
/// <summary> /// <para> /// Saves the given method definition in NESTED hierarchical structure. /// </para> /// </summary> /// /// <param name="name"> /// The method unique name. /// </param> /// <param name="definition"> /// The method definition to be saved. /// </param> /// <param name="parent"> /// The methods configuration. /// </param> private void SaveNestedMethodDefinition(IConfiguration parent, string name, MethodCallDefinition definition) { // The config of the definition IConfiguration methodConfig = new DefaultConfiguration(name); // Write all simple attributes of the definition AddNewNestedConfig(methodConfig, ConfigIgnoreCase, definition.IgnoreCase); AddNewNestedConfig(methodConfig, ConfigMethodName, definition.MethodName); AddNewNestedConfig(methodConfig, ConfigIsProperty, definition.IsProperty); if (definition.ParamTypes.Length > 0) { // Write the parameter definitions of the method SaveNestedParameters(methodConfig, definition.ParamTypes, definition.ParamValues); } // Add the new method configuration into methods config parent.AddChild(AbstractConfiguration.Synchronized(methodConfig)); }
/// <summary> /// <para> /// Saves the method definition into FLAT structure. /// </para> /// </summary> /// /// <param name="nameSpace"> /// The namespace of the configuration. /// </param> /// <param name="definition"> /// The method definition to be saved. /// </param> private void SaveFlatMethodDefinition(string nameSpace, MethodCallDefinition definition) { IConfiguration methodConfig = AddRootConfig(ConfigNamespace, nameSpace); int propertyIndex = 0; // Write all attributes of the method definition AddNewFlatConfig(methodConfig, ++propertyIndex, ConfigIgnoreCase, definition.IgnoreCase); AddNewFlatConfig(methodConfig, ++propertyIndex, ConfigMethodName, definition.MethodName); AddNewFlatConfig(methodConfig, ++propertyIndex, ConfigIsProperty, definition.IsProperty); if (definition.ParamTypes.Length > 0) { // Write parameter definitions SaveFlatParameters( nameSpace + "." + ConfigParameters, definition.ParamTypes, definition.ParamValues); } }