Не удается заставить 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": невозможно заполнить зависимости любого из общедоступных конструкторов. Доступные конструкторы: новый WeatherForecastController(IDataAccess dataAccess,
ILogger<Test3._1.Controllers.WeatherForecastController>
logger) * IDataAccess не зарегистрирован в этом контейнере и не может быть автоматически обнаружен какой-либо отсутствующей семейной политикой
1 ответ
Сообщение об ошибке указывает, что контейнер не может разрешить зависимости контроллера. Убедитесь, что эти зависимости зарегистрированы в контейнере, чтобы он знал, как их разрешить при активации контроллеров.
Это потому, что отдельные контейнеры настраиваются в Startup
и тот, который используется фреймворком, не знает о IDataAccess
как Scan
не применялся к его контейнеру.
Справочник Ламара - Интеграция с 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
}