Element autoService

Overview

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 IoCConfiguration_autoService.xml 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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
namespace IoC.Configuration.Tests.AutoService.Services
{
    public interface IActionValidatorFactoryBase
    {
        IReadOnlyList<IActionValidator> GetValidators(int actionTypeId, string projectGuid);
    }

    public interface IActionValidatorFactory : IActionValidatorFactoryBase
    {
        Guid PublicProjectId { get; }
        IActionValidator DefaultActionValidator { get; }
        IReadOnlyList<IActionValidator> 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 Element autoProperty and Element autoMethod

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
<dependencyInjection>
<!--Some other service bindings specified here-->
    <autoGeneratedServices>
        <autoService interface="IoC.Configuration.Tests.AutoService.Services.IActionValidatorFactory">

            <autoProperty name="DefaultActionValidator"
                          returnType="SharedServices.Interfaces.IActionValidator">
                <injectedObject
                    type="IoC.Configuration.Tests.AutoService.Services.ActionValidatorDefault"/>
            </autoProperty>

            <autoProperty name="PublicProjectId" returnType="System.Guid" >
                <object type="System.Guid" value="95E352DD-5C79-49D0-BD51-D62153570B61"/>
            </autoProperty>

            <autoMethod name="GetValidators"
                        returnType="System.Collections.Generic.IReadOnlyList[SharedServices.Interfaces.IActionValidator]"
                        reuseValue="true">
                <methodSignature>
                    <!--paramName attribute is optional, however it
                    makes the auto-implementation more readable. -->
                    <object paramName="actionType" typeRef="ActionTypes"/>
                    <object paramName="projectGuid" type="System.Guid"/>
                </methodSignature>

                <if parameter1="_classMember:SharedServices.DataContracts.ActionTypes.ViewFilesList"
                    parameter2="8663708F-C707-47E1-AEDC-2CD9291AD4CB">
                    <collection>

                        <constructedValue type="SharedServices.Implementations.ActionValidator1">
                            <parameters>
                              <int32 name="intParam" value="7"/>
                            </parameters>
                        </constructedValue>

                        <injectedObject type="SharedServices.Implementations.ActionValidator3" />

                        <!--Plugin1ActionValidator belongs to Plugin1. If we disable this plugin,
                            the injectedObject element below will not be included in
                          returned collection.-->
                        <injectedObject type="TestPluginAssembly1.Implementations.Plugin1ActionValidator"/>
                    </collection>
                </if>

                <if parameter1="_classMember:SharedServices.DataContracts.ActionTypes.ViewFileContents"
                    parameter2="F981F171-B382-4F15-A8F9-FE3732918D3F">
                    <collection>
                        <injectedObject type="SharedServices.Implementations.ActionValidator1" />
                    </collection>
                </if>

                <!--If none of conditions above are true, the default value will be returned by
                interface implementation.-->
                <default>
                    <collection>
                        <!--We can also call a method or property in auto-generated interface, or in
                            one of its base interfaces.-->
                        <classMember class="IoC.Configuration.Tests.AutoService.Services.IActionValidatorFactory"
                                     memberName="DefaultActionValidator"/>

                        <injectedObject type="SharedServices.Implementations.ActionValidator3" />

                        <injectedObject type="DynamicallyLoadedAssembly2.ActionValidator4"/>
                    </collection>
                </default>
            </autoMethod>

            <!--Overloaded method GetValidators uses parameters of types System.Int32 and System.string,
                instead of SharedServices.DataContracts.ActionTypes and System.Guid, as in case above.-->
            <autoMethod name="GetValidators"
                        returnType="System.Collections.Generic.IReadOnlyList[SharedServices.Interfaces.IActionValidator]">
                <methodSignature>
                    <!--paramName attribute is optional, however it makes the auto-implementation
                        more readable. -->
                    <int32 paramName="actionTypeId"/>
                    <string paramName="projectGuid" />
                </methodSignature>

                <!-- Attributes parameter1 and parameter2 map values of parameters param1 and param2 in
                    GetInstances() method to returned values. -->
                <if parameter1="0" parameter2="8663708F-C707-47E1-AEDC-2CD9291AD4CB">
                    <collection>
                        <injectedObject type="SharedServices.Implementations.ActionValidator3" />
                        <injectedObject type="IoC.Configuration.Tests.AutoService.Services.ActionValidator4" />
                    </collection>
                </if>

                <default>
                    <collection>
                        <!--We can also call a method or property in auto-generated interface, or
                            in one of its base interfaces.-->
                        <classMember class="IoC.Configuration.Tests.AutoService.Services.IActionValidatorFactory"
                                     memberName="DefaultActionValidator"/>
                        <injectedObject type="SharedServices.Implementations.ActionValidator3" />
                        <classMember class="IoC.Configuration.Tests.AutoService.Services.StaticAndConstMembers"
                                     memberName="GetDefaultActionValidator" />
                        <classMember class="IoC.Configuration.Tests.AutoService.Services.IActionValidatorValuesProvider"
                                     memberName="AdminLevelActionValidator"/>
                    </collection>
                </default>
            </autoMethod>
        </autoService>
    </autoGeneratedServices>
</dependencyInjection>

Explanation of autoMethod for method IActionValidatorFactory.GetValidators(…) above

The autoMethod element above for method System.Collections.Generic.IReadOnlyList<SharedServices.Interfaces.IActionValidator> 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:

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));
    }
}

More details on configuring autoProperty and autoMethod are available at the links below: