Не удается заставить Lamar (IOC) разрешить зависимости контроллера API в .NET Core 3.1

Я получаю сообщение об ошибке при попытке вызвать указанный ниже контроллер с помощью Lamar для разрешения зависимостей во время выполнения.

Я пробовал .AddControllersAsServices() и без, но все равно получил тот же результат.

С использованием

  • ASP.NET Core: 3.1
  • Ламар

Container.GetInstance<IDataAccess>() работает в окне просмотра, но не разрешается во время выполнения

Container.WhatDoIHave() также показывает, что существует зависимость

Вопрос?
Что мне не хватает в конфигурации Lamar для разрешения контроллеров?

[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>();

            });
}

При обработке запроса возникло необработанное исключение.

LamarException: невозможно создать зарегистрированный экземпляр weatherForecastController для 'Test3._1.Controllers.WeatherForecastController': невозможно заполнить зависимости ни одного из общедоступных конструкторов Доступные конструкторы: new WeatherForecastController (IDataAccess dataAccess, ILogger<Test3._1.Controllers.WeatherForecastController> logger) * IDataAccess не зарегистрирован в этом контейнере и не может быть автоматически обнаруженным любой отсутствующей семейной политикой


person William Zink    schedule 06.01.2020    source источник
comment
Сообщение об ошибке указывает, что контейнер не может разрешить зависимости контроллера. Убедитесь, что эти зависимости зарегистрированы в контейнере, чтобы он знал, как их разрешить при активации контроллеров.   -  person Nkosi    schedule 06.01.2020
comment
Вы настраиваете отдельные контейнеры в своем автозагрузке   -  person Nkosi    schedule 06.01.2020


Ответы (1)


Сообщение об ошибке указывает, что контейнер не может разрешить зависимости контроллера. Убедитесь, что эти зависимости зарегистрированы в контейнере, чтобы он знал, как их разрешить при активации контроллеров.

Это связано с тем, что в Startup настраиваются отдельные контейнеры, а тот, который используется фреймворком, не знает IDataAccess, поскольку Scan не был применен к его контейнеру.

Ссылка Lamar - интеграция с 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
}
person Nkosi    schedule 06.01.2020
comment
Это решило мою проблему, вы были абсолютно правы. Я увяз в мысли, что мне нужно создать Контейнер на моей стороне, не понимая, что .UseLamar () делает это за меня. Я ценю, что вы так быстро отвечаете и помогаете. Спасибо! - person William Zink; 06.01.2020