Службы консольного приложения.NET Core.AddAutofac() не работает
Я пытаюсь использовать Autofac с консольным приложением.NET Core, используя Microsoft.Extensions.DependencyInjection
а также Autofac.Extensions.DependencyInjection
пакеты, но методы загрузки внутри моих модулей никогда не вызываются и приводят к Program
быть нулевым во время разрешения. Я бы ожидал, что они загрузятся либо, когда я позвонил 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 ответа
Согласно этому вопросу, когда AddAutofac
метод был добавлен в документацию, он также был разделен между ASP.NET Core и .NET Core. По-видимому, AddAutofac
специфичен для основных приложений ASP.NET (отсюда и разные документы).
Для консольных приложений регистрация должна выглядеть так:
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();
}
}
Ваша точка входа должна быть Program.cs
в основном приложении dotnet. Также я не уверен, почему у вас есть частный метод 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;
}
}