【问题标题】:asp.net core Dependency Injection into System.ComponentModel.TypeConverterasp.net core 依赖注入到 System.ComponentModel.TypeConverter
【发布时间】: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&lt;ModelServiceVersionConverter&gt;();

在控制器上的动作中使用时

        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


【解决方案1】:

假设您创建了一个自定义Attribute 并将其应用于方法或类。在这种情况下构造函数 DI 会起作用吗?

没有。除非您使用 specific asp.net-core attributes like ServiceFilterAttribute,否则不支持此功能。

所以你需要重新设计你的类或者静态访问 DI 容器IServiceProvider

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    • 2019-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多