【问题标题】:Using autofac in asp.net core 2.2在 asp.net core 2.2 中使用 autofac
【发布时间】:2019-07-21 05:26:43
【问题描述】:

我正在尝试将最新的 Autofac 与 asp.net core 2.2 项目一起使用。但是 autofac 的文档似乎已经过时了。 我正在尝试在没有 ConfigureContainer 的情况下使用 autofac:

// ConfigureServices is where you register dependencies. This gets
  // called by the runtime before the Configure method, below.
  public IServiceProvider ConfigureServices(IServiceCollection services)
  {
    // Add services to the collection.
    services.AddMvc();

    // Create the container builder.
    var builder = new ContainerBuilder();

    // Register dependencies, populate the services from
    // the collection, and build the container.
    //
    // Note that Populate is basically a foreach to add things
    // into Autofac that are in the collection. If you register
    // things in Autofac BEFORE Populate then the stuff in the
    // ServiceCollection can override those things; if you register
    // AFTER Populate those registrations can override things
    // in the ServiceCollection. Mix and match as needed.
    builder.Populate(services);
    builder.RegisterType<MyType>().As<IMyType>();
    this.ApplicationContainer = builder.Build();

    // Create the IServiceProvider based on the container.
    return new AutofacServiceProvider(this.ApplicationContainer);
  }

但在 asp.net core 2.2 中 ConfigureServices 方法签名不同

public void ConfigureServices(IServiceCollection services)
{
}

没有返回类型。 有人知道如何在 asp.net core 2.2 中使用 autofac 吗?

【问题讨论】:

标签: c# .net asp.net-core .net-core autofac


【解决方案1】:

你需要使用这个包:

Autofac.Extensions.DependencyInjection

在您的 program.cs 中,只需使用以下代码行:

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        return WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .ConfigureServices(services => services.AddAutofac());
    }

在你的 startup.cs 中,创建一个名为

的方法
    public void ConfigureContainer(ContainerBuilder builder)
    {
    }

并使用“builder”来注册您想要的任何内容。 Autofac 会自己找到这个方法。

您无需再拨打任何builder.Build()

以下备注为了执行带有注入值的循环代码,您需要添加

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddHostedService<MyHostedService>();
    ...
}

public class MyHostedService : IHostedService
{
    private Timer _timer;
    private IInjectedService _myInjectedService;

    public MyHostedService(IServiceProvider services)
    {
        var scope = services.CreateScope();

        _myInjectedService = scope.ServiceProvider.GetRequiredService<IInjectedService>();
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        _timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromMinutes(5));

        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _timer?.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
    }

    private async void DoWork(object state)
    {
        _myInjectedService.DoStuff();
    }
}

【讨论】:

  • OP 明确表示他们希望避免使用ConfigureContainer
  • 在我的应用程序中,我有一个每五分钟运行一次的服务。我该如何解决?它不是任何控制器的一部分。这是一个单例服务,每 n 分钟运行一次。使用你上面提到的方法我不能这样做,因为我没有对 IContainer 对象的引用
  • @pantonis 刚刚使用注入添加了代码,这要归功于参数(无法访问 IContainer)
  • @hugo 当有 HostedServices 时存在竞争条件,因为它们被添加到 ConfigureServices 中,并且我的 autofac 寄存器被添加到在 ConfigureServices 之后调用的 ConfigureContainer 中。
  • @pantonis ConfigureServices 在 ConfigureContainer 之前被调用,但在 HostedService 的创建之前没有被调用(至少,我在 dotnet core 2.x 下的项目没有问题
猜你喜欢
  • 1970-01-01
  • 2019-08-25
  • 1970-01-01
  • 2020-08-09
  • 1970-01-01
  • 2020-02-25
  • 2019-03-30
  • 1970-01-01
  • 2020-05-25
相关资源
最近更新 更多