【发布时间】:2021-07-21 16:26:04
【问题描述】:
我有一个服务和 ILogger 需要在我的 TypeConverter 中使用,但没有使用或触发带有参数的构造函数,并且我的记录器和服务在转换类型时保持为空。
public class ModelServiceVersionConverter : TypeConverter
{
private static readonly Type StringType = typeof(string);
private static readonly Type VersionType = typeof(ModelServiceVersion);
private readonly ModelServiceVersions modelServiceVersions;
private readonly ILogger<ModelServiceVersionConverter> logger;
public ModelServiceVersionConverter()
{
}
public ModelServiceVersionConverter(ModelServiceVersions modelServiceVersions, ILogger<ModelServiceVersionConverter> logger)
{
this.modelServiceVersions = modelServiceVersions;
this.logger = logger;
}
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) =>
sourceType == StringType ||
sourceType == VersionType ||
base.CanConvertFrom(context, sourceType);
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is null)
{
return this.modelServiceVersions.ServiceVersions.Last();
}
var modelServiceVersion = this.modelServiceVersions.ServiceVersions.FirstOrDefault(x => x == value.ToString());
if (modelServiceVersion is null)
{
var errorMessage = $"Version {value} unexpected. No implementation of {nameof(IModelService)} for this version.";
this.logger.LogError(errorMessage);
throw new ArgumentException(errorMessage);
}
return modelServiceVersion;
}
}
ModelServiceVersion 类非常简单,并且具有TypeConverter 属性。
[TypeConverter(typeof(ModelServiceVersionConverter))]
public class ModelServiceVersion : ValueObject, IComparer<ModelServiceVersion>
{
private readonly string version;
public static ModelServiceVersion New(string version)
{
return new ModelServiceVersion(version);
}
private ModelServiceVersion(string version) =>
this.version = version;
public static implicit operator string(ModelServiceVersion modelServiceVersion) => modelServiceVersion.version;
public static implicit operator ModelServiceVersion(StringValues stringValues) => New(stringValues[0]);
protected override IEnumerable<object> GetEqualityComponents()
{
yield return this.version;
}
public int Compare(ModelServiceVersion x, ModelServiceVersion y)
{
// TODO these rules can and will likely change
var versionNumberX = FirstOrDefaultDigit(x?.version);
var versionNumberY = FirstOrDefaultDigit(x?.version);
if (y is null || versionNumberY is null)
{
return 1;
}
if (x is null || versionNumberX is null)
{
return -1;
}
if (versionNumberX == versionNumberY)
{
return 0;
}
return versionNumberX > versionNumberY ? 1 : -1;
static int? FirstOrDefaultDigit(string versionString) =>
versionString?.ToCharArray().FirstOrDefault(IsDigit);
}
}
服务全部注册到Microsoft.Extensions.DependencyInjection.IServiceCollection。
我已经尝试注册为作用域,但它没有触发类型转换器构造函数来注入依赖项。
services.AddScoped<ModelServiceVersionConverter>();
在控制器上的动作中使用时
public async Task<IActionResult> GetPrediction([FromRoute] int decisionModelId, [FromQuery] ModelServiceVersion version, [FromBody] GetPredictionModelRequest.Request request)
{
var result = await this.predictionModelQueries.GetPrediction(new GetPredictionModelRequest(decisionModelId, request));
return this.Ok(result);
}
任何想法我哪里出错了?
非常感谢任何帮助。
【问题讨论】:
-
“不工作”对我们没有帮助。在什么情况下它不起作用?你如何使用它?您收到错误消息吗?等等等等。
-
没有错误消息没有错误,在尝试将数据绑定到类型时,容器没有使用构造函数。正在触发类型转换器 convert from 方法
-
@DavidG 我在上面添加了一个更好的解释,谢谢你的回复。
标签: c# asp.net-core asp.net-web-api dependency-injection type-conversion