======================= Element **autoService** ======================= .. contents:: :local: :depth: 5 The XML configuration file has an element **autoService** that can appear in any order under "iocConfiguration/dependencyInjection/autoGeneratedServices" and "iocConfiguration/pluginsSetup/pluginSetup/dependencyInjection/autoGeneratedServices" elements for providing instructions to **IoC.Configuration** to auto-generate an implementation for an interface. .. note:: Refer to :doc:`../../sample-files/IoCConfiguration_autoService.generated` and tests in `AutoServiceSuccessfulLoadTests.cs `_ for more examples on **autoService** element. Consider the interface **IoC.Configuration.Tests.AutoService.Services.IActionValidatorFactory** below, that extends **IoC.Configuration.Tests.AutoService.Services.IActionValidatorFactoryBase**: .. code-block:: csharp :linenos: namespace IoC.Configuration.Tests.AutoService.Services { public interface IActionValidatorFactoryBase { IReadOnlyList GetValidators(int actionTypeId, string projectGuid); } public interface IActionValidatorFactory : IActionValidatorFactoryBase { Guid PublicProjectId { get; } IActionValidator DefaultActionValidator { get; } IReadOnlyList GetValidators(ActionTypes actionType, Guid projectGuid); void SomeMethodNotInConfigFile(int param1, string param2); int SomePropertyNotInConfigFile { get; } } } We want to configure auto-generation of **IoC.Configuration.Tests.AutoService.Services.IActionValidatorFactory** in configuration file. However, we are interested only in specifying the auto-generation of properties **IActionValidatorFactory.DefaultActionValidator** and **IActionValidatorFactory.PublicProjectId**, as well as in auto-generation of two overloaded methods **IActionValidatorFactory.GetValidators(ActionTypes actionType, Guid projectGuid)** and **IActionValidatorFactoryBase.GetValidators(int actionTypeId, string projectGuid)**. We can use child elements **autoProperty** and **autoMethod** to specify the implementation of methods and properties in interface **IoC.Configuration.Tests.AutoService.Services.IActionValidatorFactory** and its parents (i.e., in this case **IoC.Configuration.Tests.AutoService.Services.IActionValidatorFactoryBase**). **IoC.Configuration** will generate default implementations for methods and properties, for which no auto-implementation is configured under element **autoService**. For example method **SomeMethodNotInConfigFile()** is not configured in example below, so the generated implementation will return **default(System.Int32)**. .. note:: More details on **autoProperty** and **autoMethod** elements are provided at :doc:`./auto-property` and :doc:`./auto-method` .. code-block:: xml :linenos: Explanation of **autoMethod** for method **IActionValidatorFactory.GetValidators(...)** above --------------------------------------------------------------------------------------------- The **autoMethod** element above for method **System.Collections.Generic.IReadOnlyList IActionValidatorFactory.GetValidators(ActionTypes actionType, Guid projectGuid)** instructs **IoC.Configuration** to generate such an implementation that: - If actionType==SharedServices.DataContracts.ActionTypes.ViewFilesList.ViewFilesList and projectGuid=="8663708F-C707-47E1-AEDC-2CD9291AD4CB", then collection of three objects will be returned of the following types: **SharedServices.Implementations.ActionValidator1**, **SharedServices.Implementations.ActionValidator3**, and **TestPluginAssembly1.Implementations.Plugin1ActionValidator**. - If actionType==SharedServices.DataContracts.ActionTypes.ViewFilesList.ViewFileContents and projectGuid=="F981F171-B382-4F15-A8F9-FE3732918D3F", then collection of one object will be returned of type **SharedServices.Implementations.ActionValidator1**. - For all other values of parameters, collection of three objects specified under **default** element will be returned. Some notes: ----------- - The service type in **autoService** element that is specified using attribute **interface** or **interfaceRef** should be an interface. .. note:: Attribute **interfaceRef** is used to reference a type declared in **typeDefinition** element. - **IoC.Configuration** will setup a singleton type binding to map the interface specified in **autoService** element to the auto-generated implementation. - To use the autogenerated implementation, just inject the interface (in this case **DynamicallyLoadedAssembly2.IActionValidatorFactory1**) using constructor or property injection. - **IoC.Configuration** allows configuring auto-implemented properties and methods from the interface specified in **autoService** element, as well as from any of its parent or ancestor interfaces. Using auto-generated implementation ----------------------------------- Here is an example of using the auto-generated implementation for **DynamicallyLoadedAssembly2.IActionValidatorFactory1**: .. code-block:: csharp public class TestActionValidatorFactory1 { public TestActionValidatorFactory1( IoC.Configuration.Tests.AutoService.Services.IActionValidatorFactory actionValidatorFactory) { var actionValidatorsList = actionValidatorFactory.GetValidators( ActionTypes.ViewFilesList, Guid.Parse("95E352DD-5C79-49D0-BD51-D62153570B61")) Assert.AreEqual(3, actionValidatorsList.Count); Assert.IsInstanceOfType(actionValidatorsList[0], typeof(SharedServices.Implementations.ActionValidator1)); Assert.IsInstanceOfType(actionValidatorsList[1], typeof(SharedServices.Implementations.ActionValidator3)); Assert.IsInstanceOfType(actionValidatorsList[2], typeof(TestPluginAssembly1.Implementations.Plugin1ActionValidator)); } } Element **autoMethod** ---------------------- Element **autoMethod** is used to configure the auto-generated implementation of a method in interface specified in element **autoService**. An example of **autoMethod** elements is provided in :doc:`index`. In this section some specifics of this element will be provided. The format of **autoMethod** ============================ Method name and return type in **autoMethod** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Method name is specified using the attribute **name**. - Method return value type is specified using the attribute **returnType** and optional attribute **assembly**, or alternatively using attribute **returnTypeRef** to reference a type defined in sole **/iocConfiguration/typeDefinitions/typeDefinition** element. .. note:: Even though we only need the method name and signature, to identify the method, the return type makes the configuration more readable. Also, the return type serves as an additional way to identify the method, if a method with similar name and signature exists in multiple extended interfaces. The example below demonstrates how method name and return type are specified: .. code-block:: xml :linenos: Method signature ~~~~~~~~~~~~~~~~ Child element **methodSignature** is used to specify the auto-implemented method signature. If the method has no parameters, no **methodSignature** element is necessary. Otherwise, this element should be present, which should list the method parameters. The example below demonstrates how method signature is specified: .. code-block:: xml :linenos: Specifying the return values ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Return values are specified by using any number of optional **if** elements, followed by required **default** element. - Specifying a return value using element **if** Element **if** is used to specify a return value by providing values for up to 10 parameters using attributes **parameter1**, **parameter2**, ..., **parameter10**. Attribute **parameter1** corresponds to the first parameter in **methodSignature** element, attribute **parameter2** corresponds to the second parameter in **methodSignature** element, and so on. The number of parameter attributes should be the same as the number of parameters in element **methodSignature**. The method auto-implemented by **IoC.Configuration** will return the value specified in child element of **if** element, if parameters in method call are equal to the values in attributes **parameter1**, **parameter2**, etc. .. note:: The child of **if** element should be a value initializer element, such as **collection**, **int32**, **constructedValue**, **injectedObject**, etc. Refer to :doc:`../value-initialization-elements/index` for more details on value initializer elements. The value of parameter attribute is one of the following: - A value that will be de-serialized by a parameter serializer to a value of the parameter (example ). .. note:: Refer to :doc:`../parameter-serializers` for more details on parameter serializers. Example (see **parameter2** with value "**8663708F-C707-47E1-AEDC-2CD9291AD4CB**"): .. code-block:: xml - A class member specified by using prefix **_classMember** followed by class member path. Class member path is the full name of the type (or the type alias for some type defined in **iocConfiguration/typeDefinitions/typeDefinition** element), followed by class member name. .. note:: Refer to :doc:`../value-initialization-elements/class-member` for more details on how class members are resolved. .. note:: Class member can be can be a member in the auto-generated service as well. Example (see **parameter1** with value "**_classMember:ActionTypes.ViewFileContents**"): .. code-block:: xml - A setting value specified by using prefix **_settings** followed by a setting name. A general, or plugin setting with specified name should exist in configuration file. .. note:: Refer to :doc:`../settings` or :doc:`../plugins` for more details on general and plugin settings. Example (see **parameter2** with value "_settings:Project1Guid"): .. code-block:: xml - Specifying a return value using element **default** Element **default** is is used to specify a value to return, if none of the conditions specified in **if** elements is **true**, or if no **if** element is present. **IoC.Configuration** will return the value specified in child of **default** element. .. note:: The child of **default** element should be a value initializer element, such as **collection**, **int32**, **constructedValue**, **injectedObject**, etc. Refer to :doc:`../value-initialization-elements/index` for more details on value initializer elements. **Example:** .. code-block:: xml Referencing the auto-implemented method parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Element **parameterValue** is used to reference a parameter value in auto-implemented method of auto-generated service. This element can be used only under elements **if** or **default** under element **autoMethod**. The element uses an attribute **paramName** to reference the parameter of auto-generated method. A parameter with this name should be declared under element **../autoService/autoMethod/methodSignature**. **Example:** .. code-block:: xml :linenos: Caching the returned values ~~~~~~~~~~~~~~~~~~~~~~~~~~~ If constructing the object returned by the function is time consuming, an optional attribute **reuseValue** in element **autoMethod** can be used to cache the returned values. **Example:** .. code-block:: xml :linenos: Resolving conflicts by using **declaringInterface** in **autoMethod** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If the auto-implemented method with the specified name, signature, and return type is not in auto-implemented interface, but is present in multiple parent interfaces, **IoC.Configuration** will report an error, since it will not know which method the configuration refers to. In such rare cases an attribute **declaringInterface** can be used to specify explicitly the parent interface, where the method is declared. **Example:** .. code-block:: xml :linenos: Element **autoProperty** ------------------------ Element **autoProperty** is used to configure the auto-generated implementation of a property in interface specified in element **autoService**. An example of **autoProperty** elements is provided in :doc:`index`. In this section some specifics of this element will be provided. The Format of **autoProperty** ============================== Property name and return type in **autoProperty** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Property name is specified using the attribute **name**. - Property return value type is specified using the attribute **returnType** and optional attribute **assembly**, or alternatively using attribute **returnTypeRef** to reference a type defined in some **/iocConfiguration/typeDefinitions/typeDefinition** element. .. note:: Even though we only need the property name, to identify the property, the return type makes the configuration more readable. Also, the return type serves as an additional way to identify the property, if a property with similar name exists in multiple extended interfaces. Specifying the returned value ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The property auto-generated by **IoC.Configuration** will return the value specified in child of **autoProperty** element. The child of **autoProperty** element should be a value initializer element, such as **collection**, **int32**, **constructedValue**, **injectedObject**, etc. .. note:: Refer to :doc:`../value-initialization-elements/index` for more details on value initializer elements. **Example:** .. code-block:: xml :linenos: Resolving conflicts by using **declaringInterface** in **autoProperty** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If the auto-implemented property with the specified name, and return type is not in auto-implemented interface, but is present in multiple parent interfaces, **IoC.Configuration** will report an error, since it will not know which property the configuration refers to. In such rare cases an attribute **declaringInterface** can be used to specify explicitly the parent interface, where the property is declared. Example: .. code-block:: xml :linenos: