C#依赖注入错误:某些服务无法被实例化
我在启动我的应用时遇到了以下错误:
System.AggregateException: '某些服务无法被构造(在验证服务描述符时出错 'ServiceType: BestPractice.ExtendedServiceNamespace.IExtendedService
4[BestPractice.Inputs.ExtendedCreateInput,BestPractice.Inputs.ExtendedUpdateInput,BestPractice.Database.ExtendedComponent,System.Guid] Lifetime: Scoped ImplementationType: BestPractice.ExtendedServiceNamespace.ExtendedService4[BestPractice.Inputs.ExtendedCreateInput,BestPractice.Database.ExtendedComponent,BestPractice.Inputs.ExtendedUpdateInput,System.Guid]': 无法解析类型 'BestPractice.Database.IEntityRepository2[BestPractice.Database.ComponentBase,System.Guid]' while attempting to activate 'BestPractice.ExtendedServiceNamespace.ExtendedService4[BestPractice.Inputs.ExtendedCreateInput,BestPractice.Database.ExtendedComponent,BestPractice.Inputs.ExtendedUpdateInput,System.Guid]'.)'
我要注入的服务是这样的:我有一个服务接口,以及一个实现该接口的具体实现。
using BestPractice.Database;
using BestPractice.Inputs;
namespace BestPractice.ExtendedServiceNamespace;
public interface IExtendedService <TCreateInput, TUpdateInput, TEntity, TEntityId>
where TCreateInput : CreateBaseInput
where TUpdateInput : UpdateBaseInput
where TEntity : ComponentBase
{
public TEntity Create(TCreateInput input);
public Task<ComponentBase> UpdateAsync(TEntityId id, TUpdateInput input);
}
public class ExtendedService <TCreateInput, TEntity, TUpdateBaseInput, TEntityId> :
IExtendedService <TCreateInput, TUpdateBaseInput, TEntity, TEntityId>
where TCreateInput : CreateBaseInput
where TEntity : ComponentBase
where TUpdateBaseInput : UpdateBaseInput
{
IEntityRepository<ComponentBase, TEntityId> _repository;
public ExtendedService(IEntityRepository<ComponentBase, TEntityId> repository)
{
_repository = repository;
}
public virtual TEntity Create(TCreateInput input)
{
TEntity component;
component = Activator.CreateInstance(typeof(TEntity)) as TEntity ?? throw new InvalidOperationException("Component entity could not be constructed");
component.test1 = input.test1;
component.test2 = input.test2;
component.test3 = input.test3;
_repository.Add(component);
return component;
}
public virtual async Task<ComponentBase> UpdateAsync(TEntityId id, TUpdateBaseInput input)
{
var component = await _repository.FindByIdOrFailAsync(id);
await UpdateBaseValues(component, input);
return component;
}
protected async Task UpdateBaseValues(ComponentBase component, UpdateBaseInput input)
{
}
}
使用该服务的类是:BaseController
using BestPractice.Database;
using BestPractice.Exceptions;
using BestPractice.ExtendedServiceNamespace;
using BestPractice.Factory;
using BestPractice.Inputs;
using BestPractice.Outputs;
using BestPractice.Utilities;
using Microsoft.AspNetCore.Mvc;
using System.Net;
namespace BestPractice.Controllers;
public class BaseController<
TEntity,
TEntityId,
TObject,
TCreateInput,
TUpdateInput
> : ControllerBase
where TEntity : ComponentBase
where TObject : BaseObject
where TCreateInput : CreateBaseInput
where TUpdateInput : UpdateBaseInput
{
protected readonly IEntityRepository<TEntity , TEntityId> _entityRepository;
protected readonly IExtendedService<TCreateInput, TUpdateInput, TEntity, TEntityId> _service;
protected readonly IComponentFactory<TEntity, TObject> _factory;
public BaseController(
IEntityRepository<TEntity, TEntityId> repository,
IExtendedService<TCreateInput, TUpdateInput, TEntity, TEntityId> service,
IComponentFactory<TEntity, TObject> factory)
{
_entityRepository = repository;
_service = service;
_factory = factory;
}
[NonAction]
public virtual IActionResult Create(TCreateInput input)
{
try
{
TEntity component;
component = _service.Create(input);
return Ok(ApiResponseHelper.CreateSuccessResponse(_factory.Make(component)));
}
catch (EntityAlreadyExistsException ex)
{
ApiResponse<dynamic> response = ApiResponseHelper.CreateErrorResponse(HttpStatusCode.Conflict, ex.Message, ex);
return Conflict(response);
}
// return new EmptyResult();
}
}
我在我的 program.cs 文件中注册了该服务
builder.Services.AddScoped<IExtendedService<ExtendedCreateInput, ExtendedUpdateInput, ExtendedComponent, Guid>, ExtendedService<ExtendedCreateInput, ExtendedComponent, ExtendedUpdateInput, Guid>>();
如果有解释如何正确注册该服务的解答,我将不胜感激。
解决方案
为了让你的服务在处理任意泛型参数时能够被解析,你需要在注册时不指定泛型类型参数:
builder.Services.AddTransient(typeof(IExtendedService<,,,>), typeof(ExtendedService<,,,>));
然而,当我尝试使用 IExtendedService 解析该类时,仍然遇到错误。
解决方法是在 ExtendedService 类中正确排序泛型类型参数
public class ExtendedService<TCreateInput, TUpdateBaseInput, TEntity, TEntityId>
// not
// public class ExtendedService<TCreateInput, TEntity, TUpdateBaseInput, TEntityId>