ASP.NET CoreΒΆ

IoC.Configuration can be used with ASP.NET Core to replace the dependency injection container that ASP.NET Core uses. This includes also re-solving ASP.NET Core controllers.

Follow these steps to integrate IoC.Configuration with ASP.NET Core.

  1. If necessary, use an element iocConfiguration/webApi (or iocConfiguration/pluginsSetup/pluginsSetup/webApi for configuring controllers for plugins) to list the assemblies that contain ASP.NET Core controllers.

    The IoC.Configuration user will have to iterate this assemblies and register them with ASP.NET Core, as will be shown in code in Step 3 below.

    Note

    Element webApi is optional, and is only needed if we want to use IoC.Configuration to register controllers specified in a different assembly.

    Here is an example of webApi element with an assembly with ASP.NET Core controllers:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
        <webApi>
            <controllerAssemblies>
                <!--
                Specify assemblies with API controllers.
                The user of IoC.Configuration should add the assemblies to MVC using
                IMvcBuilder.AddApplicationPart(System.Reflection.Assembly)
                -->
                <controllerAssembly assembly="dynamic1"></controllerAssembly>
            </controllerAssemblies>
        </webApi>
    
  2. If any assemblies with ASP.NET Core controllers were specified in Step 1, register bindings for controllers in these assemblies in dependency injection elements iocConfiguration/dependencyInjection/ or iocConfiguration/pluginsSetup/pluginSetup/dependencyInjection/.

Here is an exert from the configuration file demonstrating Steps 1 and 2.

  • Element webApi on line 9 lists an assembly with an alias smart_xml_docs as an assembly with ASP.NET Core controllers (see Assemblies and Probing Paths on how to register assemblies).
  • Element selfBoundService on line 17 specifies a binding for an ASP.NET Core controller WebFileSystemApi.SmartXmlDocs.Controllers.SmartXmlTestController in assembly with alias smart_xml_docs.
 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
    <pluginsSetup>
        <pluginSetup plugin="SmartXmlDocs">
            <pluginImplementation
                type="WebFileSystemApi.SmartXmlDocs.SmartXmlDocsPlugin"
                assembly="smart_xml_docs">
            </pluginImplementation>
            <settings>
            </settings>
            <webApi>
                <controllerAssemblies>
                    <controllerAssembly assembly="smart_xml_docs"/>
                </controllerAssemblies>
            </webApi>
            <dependencyInjection>
                <modules />
                <services>
                    <selfBoundService
                        type="WebFileSystemApi.SmartXmlDocs.Controllers.SmartXmlTestController"
                        assembly="smart_xml_docs" scope="transient" >
                    </selfBoundService>
                </services>
                <autoGeneratedServices>
                </autoGeneratedServices>
            </dependencyInjection>
        </pluginSetup>
    </pluginsSetup>

Here is the code for controller class WebFileSystemApi.SmartXmlDocs.Controllers.SmartXmlTestController:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
using Microsoft.AspNetCore.Mvc;
namespace WebFileSystemApi.SmartXmlDocs.Controllers
{
    [Route("[controller]/[action]")]
    public class SmartXmlTestController : Controller
    {
        [HttpGet("{smartXmlFileId:long}")]
        public string SmartXmlDoc(long smartXmlFileId)
        {
            return $"Smart XML File Id is {smartXmlFileId}";
        }
    }
}
  1. Finally register IoC.Configuration with ASP.NET Core by using method public IServiceProvider ConfigureServices(IServiceCollection services) in Startup class as shown below. There are detailed code comments in the example below, so no farther explanations are provided.

    Note

    Integration with ASP.NET Core is currently supported for IoC.Configuration.Autofac. Currently, the ASP.NET Core project will need to reference the Nuget packages Autofac, IoC.Configuration, and IoC.Configuration.Autofac. In future this might be improved to support other containers as well (such as Ninject), and to avoid referencing these packages in the project.

 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
private static IContainerInfo _containerInfo;

public IServiceProvider ConfigureServices(IServiceCollection services)
{
    // Do some ASP.NET Core configuration
    var mvcBuilder = services.AddMvc()
        .AddMvcOptions(options =>
        {
            // ...
        })
        .AddJsonOptions(options =>
        {
            // ...
        })
        .AddControllersAsServices();

    var rootDirectory = AppDomain.CurrentDomain.BaseDirectory;

    // Load IoC.Configuration into iocContainerBuilder
    var iocContainerBuilder =
        new DiContainerBuilder()
            .StartFileBasedDi(
            new FileBasedConfigurationParameters(
            new FileBasedConfigurationFileContentsProvider(Path.Combine(rootDirectory, "WebFileSystem.IoC.Configuration.xml")),
                rootDirectory, new AllLoadedAssemblies())
            {
                ConfigurationFileXmlDocumentLoaded = (sender, e) =>
                {
                    // Do XML file transformations here
                }
            }, out var loadedConfiguration);

    // Register controller assemblies in webApi elements in IoC.Configuration file
    // with ASP.NET Core.
    Action<IoC.Configuration.ConfigurationFile.IWebApi> addControllersFromConfiguration =
        (webApi) =>
        {
            if (webApi == null || webApi.ControllerAssemblies == null)
                return;

            foreach (var controllerAssembly in webApi.ControllerAssemblies.Assemblies)
            {
                if (controllerAssembly.LoadedAssembly != null)
                    mvcBuilder.AddApplicationPart(controllerAssembly.LoadedAssembly);
            }
        };

    // Register controller assemblies in iocConfiguration/webApi element.
    addControllersFromConfiguration(loadedConfiguration.WebApi);

    // Now register controller assemblies in webApi elements under
    // iocConfiguration/pluginsSetup/pluginSetup elements.
    foreach (var pluginSetup in loadedConfiguration.PluginsSetup.AllPluginSetups)
    {
        if (pluginSetup.Enabled)
            addControllersFromConfiguration(pluginSetup.WebApi);
    }

    // Build the Autofac container builder and start the IoC.Configuration.
    var autofacContainerBuilder = new ContainerBuilder();

    // Register ASP.NET Core services with Autofac, however skip
    // the services, the full name of which starts with "WebFileSystemApi".
    // Registering bindings of non-Microsoft services will be done in
    // IoC.Configuration file.
    autofacContainerBuilder.Populate(
        services.Where(x =>
            !x.ServiceType.FullName.StartsWith("WebFileSystemApi", StringComparison.Ordinal)));

    // Since we provide an instance of
    // IoC.Configuration.Autofac.AutofacDiContainer,
    // IoC.Configuration.Autofac will not create and build instance of
    // Autofac.ContainerBuilder.
    // In this case, we need to call iocContainerStarter.Start() only after
    // we call autofacContainerBuilder.Build() below.
    var iocContainerStarter = iocContainerBuilder
        .WithDiContainer(new AutofacDiContainer(autofacContainerBuilder))
        .RegisterModules();

    var container = autofacContainerBuilder.Build();
    _containerInfo = iocContainerStarter.Start();

    return new AutofacServiceProvider(container);
}
1
2
3
4
5
    // Make sure OnShutdown() is called on ASP.NET Core shutdown, to dispose of _containerInfo.
    private void OnShutdown()
    {
        _containerInfo?.Dispose();
    }