.NET Core Console App services.AddAutofac()不工作

时间:2018-03-18 23:55:56

标签: .net-core console-application autofac autofac-configuration

我正在尝试使用Microsoft.Extensions.DependencyInjectionAutofac.Extensions.DependencyInjection软件包将Autofac与.NET Core控制台应用程序一起使用,但我的模块中的加载方法永远不会被调用并导致Program为null在决议期间。我打算在调用AddAutofac()扩展方法或构建服务提供程序时加载它们。

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

2 个答案:

答案 0 :(得分:1)

根据this issue,当AddAutofac方法添加到文档中时,它也在ASP.NET Core.NET Core之间分开。显然,AddAutofac特定于ASP.NET核心应用程序(因此不同的文档)。

对于console applications,注册应如下所示:

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

答案 1 :(得分:0)

在dotnet核心应用程序中,您的入口点应为Program.cs。另外,我不确定为什么要使用私有的Main方法。但是无论如何,请按照以下步骤操作

Autofac文档说:

  

您不必使用Microsoft.Extensions.DependencyInjection。如果你   没有编写需要它的.NET Core应用程序,或者如果您不使用它   您可以使用的其他库提供的任何DI扩展   直接使用Autofac。

您实际上可以使用不带扩展名的Autofac。请参阅一个非常基本的dotnet核心控制台应用程序示例。确保您安装了nuGet软件包Autofac(当前版本4.8.1)

我们可以有一个界面:

public interface IPrintService
{
    void Print();
}

以及此接口的实现。

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

那么我们可以有一个类,其中可以通过其构造函数注入IPrintService

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

最后,在主控制台程序中,我们可以配置Autofac并注册服务。请注意,我决定自动激活Client实例只是为了说明一个示例,并证明Autofac正在注入所需的实现。

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