Reputation: 5075
I need to configure Autofac DI container in ASP.NET CORE 3.1 Web API application and call register class from the container in Web API controller. I install Autofac.Extensions.DependencyInjection (6.0.0) and try to register container in my Startup.cs class but I am not able to use service. Also, do I need to configure the container in ConfigureServices(IServiceCollection services) class? The debugger does not hit IoCConfigurator() class after hitting point builder.RegisterModule(new IoCConfigurator());
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>();
});
}
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());
}
public class IoCConfigurator: Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<NotifyService>().As<INotificationService>();
builder.RegisterType<UsersService>().AsSelf();
}
}
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);
}
}
API Controller where I want to class the UserService Class and get reference from DI container
[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;
}
Upvotes: 1
Views: 3855
Reputation: 1040
Change your code like, that is all I think
Program.cs
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterModule(new IoCConfigurator());
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
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)
{
services.AddControllers();
}
Upvotes: 0
Reputation: 2828
Here is how I set it up. From command line:
md autof
cd autof
dotnet new webapi
dotnet add package Autofac.Extensions.DependencyInjection
Then edit using VS or VSCode. Program.cs - as you had it:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
Next in Startup.cs, forget about ConfigureIoC, just register the services you want/need:
public void ConfigureContainer(ContainerBuilder builder)
{
// Register your own things directly with Autofac, like:
//builder.RegisterModule();
builder.RegisterType<NotifyService>().As<INotificationService>();
}
Then in DashboardController.cs you need to "inject" the needed services from the constructor:
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;
}
}
With console output: Your UserService was a little "out of the loop" but you can add an Interface for it and register with container and add it to injected services of the controller(s).
I could zip the whole thing up, just don't know where to put it or send it...
Upvotes: 3