1

I am attempting to use Autofac with a .NET Core console application using the Microsoft.Extensions.DependencyInjection and Autofac.Extensions.DependencyInjection packages but the load methods inside my modules never get invoked and leads to Program being null during resolution. I would have expected them to load either when I called the AddAutofac() extension method or when the service provider was built.

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.IO;

public class Startup
{
    private static void Main(string[] args)
    {               
        var services = new ServiceCollection();

        services.AddAutofac(builder =>
        {
            builder.RegisterModule(new MyFirstModule(configuration));
            builder.RegisterModule(new MySecondModule(configuration));
        });

        using (var serviceProvider = services.BuildServiceProvider())
        {
            var program = serviceProvider.GetService<Program>();
            program.Start();
        }
    }
}
Adam
  • 4,590
  • 10
  • 51
  • 84
  • 1
    The question in its current state is incomplete and therefore unclear. Read [ask] and then [edit] the question to provide a [mcve] that can be used to reproduce the problem, allowing a better understanding of what is being asked. – Nkosi Mar 19 '18 at 00:06
  • I'm not sure what other details you would be referring to? The .NET Core service container configuration seems pretty common but I have never done it outside of a WebApi project where there is no IWebHostingEnvironment. – Adam Mar 19 '18 at 04:28

2 Answers2

2

According to this issue, when the AddAutofac method was added to the documentation, it was also split between ASP.NET Core and .NET Core. Apparently, AddAutofac is specific to ASP.NET Core applications (hence the different documents).

For console applications, the registration should look like:

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.IO;

public class Startup
{
    private static void Main(string[] args)
    {               
        var services = new ServiceCollection();
        var builder = new ContainerBuilder();

        // Once you've registered everything in the ServiceCollection, call
        // Populate to bring those registrations into Autofac. This is
        // just like a foreach over the list of things in the collection
        // to add them to Autofac.
        containerBuilder.Populate(services);

        // Make your Autofac registrations. Order is important!
        // If you make them BEFORE you call Populate, then the
        // registrations in the ServiceCollection will override Autofac
        // registrations; if you make them AFTER Populate, the Autofac
        // registrations will override. You can make registrations
        // before or after Populate, however you choose.
        builder.RegisterModule(new MyFirstModule(configuration));
        builder.RegisterModule(new MySecondModule(configuration));

        // Creating a new AutofacServiceProvider makes the container
        // available to your app using the Microsoft IServiceProvider
        // interface so you can use those abstractions rather than
        // binding directly to Autofac.
        var container = containerBuilder.Build();
        var serviceProvider = new AutofacServiceProvider(container);

        var program = serviceProvider.GetService<Program>();
        program.Start();
    }
}   
NightOwl888
  • 55,572
  • 24
  • 139
  • 212
0

Your entry point should be Program.cs in a dotnet core application. Also I am not sure why do you have a private Main method. But regardless, please follow these steps

Autofac documentation says that:

You don’t have to use Microsoft.Extensions.DependencyInjection. If you aren’t writing a .NET Core app that requires it or if you’re not using any of the DI extensions provided by other libraries you can consume Autofac directly.

You can actually use Autofac without extensions. See a very basic example of a dotnet core console application. Make sure you install a nuGet package Autofac (current version 4.8.1)

We can have an interface:

public interface IPrintService
{
    void Print();
}

And an implementation of this interface.

public class PrintService
    : IPrintService
{
    public void Print()
    {
        Console.WriteLine("I am a print service injected");
    }
}

then we can have, for example, a class where we inject a IPrintService through its constructor

public class Client
{
    public Client(IPrintService printService)
    {
        printService.Print();
    }
}

And finally, in the main console program we can configure Autofac and register the services. Notice that I have decided to autoActivate a Client instance just to illustrate an example and prove that Autofac is injecting the desired implementation.

class Program
{
    static void Main(string[] args)
    {
        ConfigureIoCc();
        Console.WriteLine("Using Autofac");
        Console.ReadKey();
    }

    public static IContainer ConfigureIoCc()
    {
        var builder = new ContainerBuilder();

        builder
            .RegisterType<PrintService>()
            .As<IPrintService>();

        builder
            .RegisterType<Client>()
            .AsSelf()
            .AutoActivate(); //to automatically instantiate it

        var container = builder.Build();
        return container;
    }
}
diegosasw
  • 13,734
  • 16
  • 95
  • 159