Search code examples
c#.net-core.net-6.0autofac

.NET 6 API System.InvalidOperationException


I have Autofac module like this on one class:

  public class AutofacBusinessModule:Module
  {
    protected override void Load(ContainerBuilder builder)
    {
      builder.RegisterType<ProductManager>().As<IProductService>();
      builder.RegisterType<EfProductDal>().As<IProductDal>();

      builder.RegisterType<CategoryManager>().As<ICategoryService>();
      builder.RegisterType<EfCategoryDal>().As<ICategoryDal>();

      builder.RegisterType<CustomerManager>().As<ICustomerService>();
      builder.RegisterType<EfCustomerDal>().As<ICustomerDal>();

      builder.RegisterType<RegionManager>().As<IRegionService>();
      builder.RegisterType<EfRegionDal>().As<IRegionDal>();

      builder.RegisterType<TerritoryManager>().As<ITerritoryService>();
      builder.RegisterType<EfTerritoryDal>().As<ITerritoryDal>();

      builder.RegisterType<ShipperManager>().As<IShipperService>();
      builder.RegisterType<EfShipperDal>().As<IShipperDal>();

      builder.RegisterType<EmployeeManager>().As<IEmployeeDal>();
      builder.RegisterType<EfEmployeeDal>().As<IEmployeeDal>();



      var assembly = System.Reflection.Assembly.GetExecutingAssembly();
      builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces()
        .EnableInterfaceInterceptors(new ProxyGenerationOptions()
        {
          Selector = new AspectInterceptorSelector()
        }).SingleInstance();
    }

My API code its there:

  [Route("api/[controller]")]
  [ApiController]
  public class ProductsController : Controller
  {

    private readonly IProductService _productService;
    public ProductsController(IProductService productService)
    {
      _productService = productService;
    }

    [HttpGet("getall")]
    public IActionResult GetAllProducts()
    {
      var result = _productService.GetAll();
      if (result.Success)
      {
        return Ok(result);
      }

      return BadRequest(result);
    }
  }
}

I add this on program.cs but didn't work, if lower I use .net 6 I fix it like that but I don't know how to fix .net 6 because startup doesn't exists anymore.

IHostBuilder CreateHostBuilder(string[] args) =>
  Host.CreateDefaultBuilder(args)
    .UseServiceProviderFactory(new AutofacServiceProviderFactory())
    .ConfigureContainer<ContainerBuilder>(builder =>
    {
      builder.RegisterModule(new AutofacBusinessModule());
    });

How can I fix this?

It gives me that error:

System.InvalidOperationException: Unable to resolve service for type 'TAO.Business.Abstract.IProductService' while attempting to activate 'TAO.WebApi.Controllers.ProductsController'.
   at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
   at lambda_method3(Closure , IServiceProvider , Object[] )
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass7_0.<CreateActivator>b__0(ControllerContext controllerContext)
   at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass6_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

HEADERS

Accept: /
Connection: keep-alive
Host: localhost:7019
User-Agent: PostmanRuntime/7.30.0
Accept-Encoding: gzip, deflate, br
Postman-Token: fbff062e-ca49-4f37-afc5-e8785afbd43c


Solution

  • Try the following code from migration doc:

    builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
    
    // Register services directly with Autofac here. Don't
    // call builder.Populate(), that happens in AutofacServiceProviderFactory.
    builder.Host.ConfigureContainer<ContainerBuilder>(builder => builder.RegisterModule(new AutofacBusinessModule()));
    

    Note that the "old" generic hosting model still works in .NET 6, there is no requirement to use the new minimal hosting model (but you need to copy not only CreateHostBuilder method but also contents of old Program.Main into the new Program top-level statement file).