2

I am getting an error when trying to call the controller below using Lamar to resolve the dependencies at runtime.

I have tried .AddControllersAsServices() and without and still get the same result.

Using

  • ASP.NET Core: 3.1
  • Lamar

Container.GetInstance<IDataAccess>() works inside the watch window but will not resolve at runtime

Container.WhatDoIHave() also shows that the dependency is there

Question?
What am I missing in Lamar configuration to resolve the controllers?

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    private readonly IDataAccess _dataAccess;
    private readonly ILogger<WeatherForecastController> _logger;

    public WeatherForecastController(IDataAccess dataAccess, ILogger<WeatherForecastController> logger)
    {
        _dataAccess = dataAccess;
    }

    [HttpGet]
    public IEnumerable<string> Get()
    {
        return _dataAccess.GetAll();
    }
}

Startup.cs


public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public IContainer Container { get; private set; }

    public void ConfigureContainer(ServiceRegistry services)
    {
        Container = new Container(cfg =>
        {
            cfg.Scan(scanner =>
            {
                scanner.AssembliesAndExecutablesFromApplicationBaseDirectory(a =>
                    a.FullName.Contains("Test3.1"));
                scanner.WithDefaultConventions();
                scanner.SingleImplementationsOfInterface();
            });
        });

        services
            .AddControllers(options =>
            {
                // Disable automatic fallback to JSON
                options.ReturnHttpNotAcceptable = true;

                // Honor browser's Accept header (e.g. Chrome)
                options.RespectBrowserAcceptHeader = true;
            })
            .AddControllersAsServices();

        services.AddMvc()
            .AddControllersAsServices();

        Container.WhatDidIScan();
        Container.WhatDoIHave();

        Console.Write("Container Instantiated");
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseHttpsRedirection();
        app.UseDefaultFiles();
        app.UseStaticFiles();
        app.UseRouting();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

Program.cs


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

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseLamar()
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder
                    .UseContentRoot(Directory.GetCurrentDirectory())
                    .UseIISIntegration()
                    .UseStartup<Startup>();

            });
}

An unhandled exception occurred while processing the request.

LamarException: Cannot build registered instance weatherForecastController of 'Test3._1.Controllers.WeatherForecastController': Cannot fill the dependencies of any of the public constructors Available constructors:new WeatherForecastController(IDataAccess dataAccess, ILogger<Test3._1.Controllers.WeatherForecastController> logger) * IDataAccess is not registered within this container and cannot be auto discovered by any missing family policy

Nkosi
  • 235,767
  • 35
  • 427
  • 472
William Zink
  • 189
  • 4
  • 15
  • The error message indicates that the container can't resolve the controller's dependencies. Make sure those dependencies are registered with the container so it knows how to resolve them when activating controllers – Nkosi Jan 06 '20 at 14:48
  • 1
    You are configuring separate containers in your Startup – Nkosi Jan 06 '20 at 14:51

1 Answers1

2

The error message indicates that the container can't resolve the controller's dependencies. Make sure those dependencies are registered with the container so it knows how to resolve them when activating controllers.

This is because separate containers are being configured in Startup and the one used by the framework is unaware of IDataAccess as the Scan was not applied to its container.

Reference Lamar - Integration with ASP.Net Core

public class Startup {

    public Startup(IConfiguration configuration) {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    //REMOVED IContainer. It is not needed

    public void ConfigureContainer(ServiceRegistry services) {

        //Apply scan to the registry used by framework so container is aware of types.
        services.Scan(scanner => {
            scanner.AssembliesAndExecutablesFromApplicationBaseDirectory(a =>
                a.FullName.Contains("Test3.1"));
            scanner.WithDefaultConventions();
            scanner.SingleImplementationsOfInterface();
        });

        services
            .AddControllers(options => {
                // Disable automatic fallback to JSON
                options.ReturnHttpNotAcceptable = true;
                // Honor browser's Accept header (e.g. Chrome)
                options.RespectBrowserAcceptHeader = true;
            })
            .AddControllersAsServices();

        services.AddMvc()
            .AddControllersAsServices();

        services.WhatDidIScan();
        services.WhatDoIHave();

        Console.Write("Container Instantiated");
    }

    //...omitted for brevity
}
Community
  • 1
  • 1
Nkosi
  • 235,767
  • 35
  • 427
  • 472
  • 1
    This solved my problem, you were totally right. I got bogged down into thinking that I had to create a Container on my end not realizing that .UseLamar() was doing that for me. I appreciate you being so quick to respond and helpful. Thanks! – William Zink Jan 06 '20 at 15:23