我有一个服务和 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);
}
有什么想法我哪里出错了吗?
非常感谢任何帮助。
答案 0 :(得分:0)
假设您已经创建了一个自定义 Attribute
并将其应用于一个方法或一个类。在这种情况下,构造函数 DI 会起作用吗?
没有。除非您使用 specific asp.net-core attributes like ServiceFilterAttribute,否则不支持此功能。
因此您需要重新设计类或对 DI 容器 IServiceProvider
进行静态访问。