【发布时间】:2019-07-02 17:14:12
【问题描述】:
我得到以下异常:
System.InvalidOperationException: '无法从根提供程序解析范围服务'OSPC.Shared.Core.Data.IRepository`1[OSPC.Configuration.Objects.SignalMetaData]'。' 在 CommandDispatcher 类中的 ActivatorUtilities.CreateInstance 行上。
在调查注入 CommandDispatcher 类的参数 serviceProvider 时,我可以在 ResolvedServices 集合中看到 122 个项目(所有与 Microsoft 相关的服务),但我在 ConfigureServices 方法中注册的服务都没有在集合中。
为什么我自己注册的服务没有出现?
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<ILogManager, LogManager>();
services.AddScoped<IDbContext>(c => new OSPCContext(Configuration.GetConnectionString("OSPCConnectionstring")));
services.AddScoped(typeof(IRepository<>), typeof(EfRepository<>));
services.AddSingleton<ICommandDispatcher, CommandDispatcher>();
}
}
public class CommandDispatcher : ICommandDispatcher
{
private readonly IServiceProvider _serviceProvider;
private readonly Dictionary<string, Type> _registeredCommands = new Dictionary<string, Type>();
public CommandDispatcher(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
_registeredCommands.Add("CreateSignalMetaData", typeof(CreateSignalMetaDataHandler));
_registeredCommands.Add("CreatePDCQueryConfig", typeof(CreatePDCQueryConfigHandler));
}
public object Dispatch(string json)
{
JObject jObject = JObject.Parse(json);
JToken jToken = jObject["type"];
if (jToken == null)
{
throw new Exception("The parameter type is missing in the JSON string (Pay attention: it is casse sensitive).");
}
Type typeCommandHandler = _registeredCommands[jToken.ToString()];
dynamic commandHandler = ActivatorUtilities.CreateInstance(_serviceProvider, typeCommandHandler);
dynamic o = jObject.ToObject(commandHandler.InputType);
return commandHandler.Handle(o);
}
}
[Route("api/[controller]")]
[ApiController]
public class ConfigurationController : ControllerBase
{
private readonly ILog _logger;
private readonly IConfigurationService _configurationService;
private readonly ICommandDispatcher _commandDispatcher;
public ConfigurationController(ICommandDispatcher commandDispatcher)
{
this._commandDispatcher = commandDispatcher;
}
// POST api/configuration
[HttpPost]
public IActionResult Post([FromBody] dynamic json)
{
var result = _commandDispatcher.Dispatch(json.ToString());
return Ok(result);
}
}
using OSPC.Configuration.Msg;
using OSPC.Configuration.Objects;
using OSPC.Shared.Core.Commands;
using OSPC.Shared.Core.Data;
using System.Collections.Generic;
namespace OSPC.Configuration.CommandHandler
{
public class CreateSignalMetaDataHandler : CommandHandlerBase<CreateSignalMetaDataRequest, CreateSignalMetaDataResponse>
{
private readonly IRepository<SignalMetaData> _signalMetaDataRepository;
public CreateSignalMetaDataHandler(IRepository<SignalMetaData> signalMetaDataRepository)
{
_signalMetaDataRepository = signalMetaDataRepository;
}
public override CreateSignalMetaDataResponse Handle()
{
Output.Success = false;
var result = new CreateSignalMetaDataResponse
{
SignalMetaDatas = new List<CreateSignalMetaDataResponse.SignalMetaData>()
};
foreach (var item in Input.Payload.SignalMetaDatas)
{
var signalMetaData = new Objects.SignalMetaData()
{
SignalName = item.SignalName,
Unit = item.Unit,
SignalDescription = item.SignalDescription,
Source = item.Source
};
_signalMetaDataRepository.Insert(signalMetaData);
result.SignalMetaDatas.Add(new CreateSignalMetaDataResponse.SignalMetaData()
{
Id = signalMetaData.Id,
SignalName = signalMetaData.SignalName,
Unit = signalMetaData.Unit,
SignalDescription = signalMetaData.SignalDescription,
Source = signalMetaData.Source
});
}
Output.Success = true;
return result;
}
}
}
【问题讨论】:
-
什么是
ActivatorUtilities? -
CreateSignalMetaDataHandler的定义是什么? -
@daniel-white ActivatorUtilities 是来自 Microsoft 的静态类(程序集 Microsoft.Extensions.DependencyInjection.Abstractions.dll)。
-
@daniel-white 目的是通过反射(基于json字符串中的“type”字段)实例化一个新的commandhandler。我想重用 StartUp 类中定义的现有 IServiceCollection,并且 ActivatorUtilities.CreateInstance 允许传递 IServiceProvider。因此,当调用命令处理程序时,依赖注入将完成它的工作。
-
@Tao Zhou 我已经在代码中添加了 CreateSignalMetaDataHandler。
标签: c# asp.net-core dependency-injection