Проблема в том, что универсальные типы оцениваются во время компиляции. Таким образом, даже если ваш HandleMessage
является общим HandleMessage<TMessage>(TMessage message)
, используемый тип TMessage
не является типом времени выполнения.
То, как вы вызываете свой метод, выглядит следующим образом:
var deserializedModel = deserial.Parse(messageBody);
reply = (WxReplyMessage_Text) await HandleMessage(deserializedModel);
Таким образом, тип времени компиляции deserializedModel
определяет, какой тип будет использоваться для аргумента универсального типа TMessage
.
Поскольку Parse
сам по себе не является универсальным, он, скорее всего, вернет базовый тип, и этот базовый тип будет использоваться для HandleMessage
. Таким образом, внутри HandleMessage
, TMessage
будет этот базовый тип, и вызов GetService<IWxMessageHandler<TMessage>>
будет использовать этот базовый тип для извлечения экземпляра службы обработчика.
Если вы хотите получить фактический обработчик, вам нужно будет получить тип услуги конкретный от поставщика услуг. И чтобы сделать это из типа времени выполнения вашего объекта сообщения, вам нужно будет использовать отражение, чтобы получить и сконструировать этот тип:
public async Task<WxMessage> HandleMessage(IWxMessage message)
{
var messageType = message.GetType();
var messageHandlerType = typeof(IWxMessageHandler<>).MakeGenericType(messageType);
var handler = _serviceProvider.GetService(messageHandlerType);
// …
}
Предполагается, что у вас есть базовый тип IWxMessage
для сообщения, и метод HandleMessage
не является универсальным. Вместо этого тип обработчика будет определен во время компиляции из конкретного типа сообщения. Обратите внимание, что у вас также должен быть некоторый базовый интерфейс для вашего обработчика сообщений, который позволяет вам вызывать метод для всех типов (в идеале просто IWxMessage
), в противном случае вам также придется использовать отражение для вызова обработчика.