首页 > 解决方案 > 在 ASP.NET CORE 3.1 Web API 中配置 Autofac DI 容器和来自控制器的消费者服务

问题描述

我需要在 ASP.NET CORE 3.1 Web API 应用程序中配置 Autofac DI 容器,并从 Web API 控制器中的容器调用注册类。我安装 Autofac.Extensions.DependencyInjection (6.0.0) 并尝试在我的 Startup.cs 类中注册容器,但我无法使用服务。另外,我需要在 ConfigureServices(IServiceCollection services) 类中配置容器吗?调试器在命中点 builder.RegisterModule(new IoCConfigurator()); 后没有命中 IoCConfigurator() 类;

程序.cs

 public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseServiceProviderFactory(new AutofacServiceProviderFactory())
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

启动.cs

 public class Startup
{
    public IConfiguration Configuration { get; }
    public ContainerBuilder containerBuilder { get; }

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
        containerBuilder = new ContainerBuilder();
    }

    public void ConfigureServices(IServiceCollection services)
    {
        ServicesConfigurator.Configure(services, Configuration);
        ConfigureIoC(services, containerBuilder);
    }

    public void ConfigureIoC(IServiceCollection services, ContainerBuilder builder)
    {

        builder.RegisterModule(new IoCConfigurator());
    }

IoCConfigurator.cs

 public class IoCConfigurator: Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<NotifyService>().As<INotificationService>();
        builder.RegisterType<UsersService>().AsSelf();
    }
 }

INotification 接口和类

 public interface INotificationService
{
   void notifyUsernameChanged(Users users);
}

   public class NotifyService : INotificationService
{
    public void notifyUsernameChanged(Users users)
    {
        string changedUsername = users.Username;

        Console.WriteLine("Username has changed to ... ");
        Console.WriteLine(changedUsername);
    }
}

用户和用户服务类

 public class Users
{
    public string Username { get; set; }

    public Users(string username)
    {
        this.Username = username;
    }  
}

public class UsersService
{
    private INotificationService _notificationService;
    public UsersService(INotificationService notificationService)
    {
        this._notificationService = notificationService;
    }

    public void ChangeUsername(Users users, string newUsername)
    {
        users.Username = newUsername;
        _notificationService.notifyUsernameChanged(users);
    }
}

我想对 UserService 类进行分类并从 DI 容器获取引用的 API 控制器

[Authorize]
[Route("txn/v1/[controller]/[action]")]
[ApiController]
public class DashboardController : ControllerBase
{

  [HttpPost("{name}")]
    public ActionResult<HelloMessage> GetMessage(string name)
    {
        // call container here...
        var result = new HelloMessage()
        {
            GivenName = name,
            ReturnMessage = "Dashboard@ Hello, Welcome to Texanite Digital"
        };

        return result;
    }

标签: asp.net-web-apiautofacasp.net-core-3.1autofac-configuration

解决方案


这是我的设置方式。从命令行:

md autof
cd autof
dotnet new webapi
dotnet add package Autofac.Extensions.DependencyInjection

然后使用 VS 或 VSCode 进行编辑。Program.cs - 正如你所拥有的:

public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseServiceProviderFactory(new AutofacServiceProviderFactory())
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });

接下来在 Startup.cs 中,忘记 ConfigureIoC,只需注册您想要/需要的服务:

public void ConfigureContainer(ContainerBuilder builder)
    {
        // Register your own things directly with Autofac, like:
        //builder.RegisterModule();
        builder.RegisterType<NotifyService>().As<INotificationService>();
    }

然后在 DashboardController.cs 中,您需要从构造函数“注入”所需的服务:

public class HelloMessage {
    public string GivenName { get; set; }
    public string ReturnMessage { get; set; }
}

//[Authorize]   Easier without Auth - don't need
[Route("[controller]")]
[ApiController]
public class DashboardController : ControllerBase
{
    private readonly INotificationService _notifyService;

    public DashboardController(INotificationService notifyService)
    {
        _notifyService = notifyService;
    }

    //[HttpPost("{name}")] - easier to test Get
    [HttpGet("{name}")]
    public ActionResult<HelloMessage> GetMessage(string name)
    {
        // call container here...
        _notifyService.notifyUsernameChanged(new Users(name));

        var result = new HelloMessage()
        {
            GivenName = name,
            ReturnMessage = $"Dashboard {name}, Welcome to Texanite Digital"
        };

        return result;
    }
}

我的结果: 浏览器截图

使用控制台输出: 带有有毒名称的控制台输出 您的 UserService 有点“脱离循环”,但您可以为其添加一个接口并注册到容器并将其添加到控制器的注入服务中。

我可以把整个东西拉上拉链,只是不知道放在哪里或发送它......


推荐阅读