Mail.ruПочта0Мой Мир0ОдноклассникиВКонтактеИгры0ЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Dependency Injection error: Unable to resolve service for type while attempting to activate, while class is registered

Максим Лео Знаток (369), открыт 5 дней назад
Я делаю централизованную распределенную систему хранения файлов на ASP и docker. У меня есть центральный узел, который делит файл на части и отправляет их воркерам, и 3 рабочих, которые хранят части файла.

Я зарегистрировал все сервисы, но у меня почему-то программа не может создать экземпляр класса WorkerFileStorageService. Весь код залил на пастебин. https://pastebin.com/LSErtNjN

Вот логи из докера:
2025-03-24 12:15:24 Node Role: central
2025-03-24 12:15:46 fail: Microsoft.AspNetCore.Server.Kestrel[13]
2025-03-24 12:15:46 Connection id "0HNBAMHLJAF7F", Request id "0HNBAMHLJAF7F:00000003": An unhandled exception was thrown by the application.
2025-03-24 12:15:46 System.InvalidOperationException: Unable to resolve service for type 'DistributedSystems_Lab3.WorkerFileStorageService' while attempting to activate 'DistributedSystems_Lab3.WorkerController'.
2025-03-24 12:15:46 at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ThrowHelperUnableToResolveService(Type type, Type requiredBy)
2025-03-24 12:15:46 at lambda_method18(Closure, IServiceProvider, Object[])
2025-03-24 12:15:46 at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass6_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
2025-03-24 12:15:46 at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next (State& next, Scope& scope, Object& state, Boolean& isCompleted)
2025-03-24 12:15:46 at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
2025-03-24 12:15:46 --- End of stack trace from previous location ---
2025-03-24 12:15:46 at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
2025-03-24 12:15:46 at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
2025-03-24 12:15:46 at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next (State& next, Scope& scope, Object& state, Boolean& isCompleted)
2025-03-24 12:15:46 at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
2025-03-24 12:15:46 --- End of stack trace from previous location ---
2025-03-24 12:15:46 at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
2025-03-24 12:15:46 at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
2025-03-24 12:15:46 at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
2025-03-24 12:15:46 at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
2025-03-24 12:15:46 at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
3 ответа
[ ] [ ] Мастер (1545) 5 дней назад
Возможно не зарегистрировал сервис, который внутри WorkerFileStorageService, либо сам WorkerFileStorageService. Это, как обычно, какая-нибудь лажа полная
S.H.I. Оракул (73174) 5 дней назад
Ваш центральный узел запускается с переменной окружения NodeRole=central. В Program.cs вы регистрируете только CentralFileStorageService для центрального узла. Но при этом контроллер WorkerController доступен для всех узлов и пытается использовать WorkerFileStorageService, который не зарегистрирован на центральном узле. Вам нужно изменить регистрацию сервисов и маршрутизацию контроллеров в зависимости от роли узла.
 using DistributedSystems_Lab3; 
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;

var builder = WebApplication.CreateBuilder(args);

string nodeRole = Environment.GetEnvironmentVariable("NodeRole") ?? "worker";
Console.WriteLine($"Node Role: {nodeRole}");

builder.Services.AddMvc();
builder.Services.AddControllers();
builder.Services.AddSingleton<HttpClient>();

// Условная регистрация сервисов в зависимости от роли узла
if (nodeRole == "central")
{
builder.Services.AddSingleton<CentralFileStorageService>();
}
else
{
builder.Services.AddSingleton<WorkerFileStorageService>();
}

var app = builder.Build();

app.MapGet("/", () => Results.Redirect("/index.html"));

app.UseStaticFiles();

app.UseRouting();
app.UseAuthorization();

// Условная регистрация контроллеров в зависимости от роли узла
if (nodeRole == "central")
{
app.MapControllerRoute(
name: "default",
pattern: "{controller=File}/{action=Index}/{id?}");
}
else
{
app.MapControllerRoute(
name: "worker",
pattern: "{controller=Worker}/{action=Index}/{id?}");
}

app.Run();
Jurijus Zaksas Искусственный Интеллект (465677) 4 дня назад
Гм... В распределенной системе все воркеры хранят все части файла. Они просто по запросу отдают их по частям, что ускоряет загрузку.
Строго по вопросу - ЕМНИП веб-сервисы такого типа регистрируют себя на каких-то серверах. Например, для SOA по умолчанию используется какой-то мелкософтовский сервер, на котором хранятся метаданные его RPC. Я бы на твоем месте копал в этом направлении.
Похожие вопросы