Не удается получить Lamar (IO C) для разрешения зависимостей контроллера API в. NET Core 3.1 - PullRequest
2 голосов
/ 06 января 2020

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

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

Использование

  • ASP. NET Core: 3.1
  • Lamar

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: Cannot построить зарегистрированный экземпляр weatherForecastController из 'Test3._1.Controllers.WeatherForecastController': невозможно заполнить зависимости ни одного из конструкторов publi c Доступные конструкторы: новый WeatherForecastController (IDataAccess dataAccess, ILogger<Test3._1.Controllers.WeatherForecastController> logger) * IDataAccess не является зарегистрирован в этом контейнере и не может быть автоматически обнаружен любой отсутствующей семейной политикой

1 Ответ

2 голосов
/ 06 января 2020

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

Это связано с тем, что в 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
}
...