You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何手动实现依赖注入?Dto类中ServiceProvider为空问题求助

在实现IValidatableObject的DTO中注入服务的解决方案

问题原因

DTO作为数据传输对象,通常由模型绑定器直接实例化,而非通过DI容器创建,因此:

  • 自定义的ServiceProvider字段不会被自动赋值
  • [FromServices]属性无法在DTO的方法中生效,框架不会处理该注入逻辑

可行解决方案

方案1:通过ValidationContext直接获取服务

在Validate方法中,利用传入的ValidationContext实例获取所需服务,无需额外定义字段:

public partial class Dto : IValidatableObject
{
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var results = new List<ValidationResult>();
        
        // 从ValidationContext获取服务
        var scService = validationContext.GetService(typeof(ISCService)) as ISCService;
        if (scService == null)
        {
            results.Add(new ValidationResult("无法获取ISCService服务"));
            return results;
        }
        
        // 调用服务并执行验证逻辑
        var data = scService.GetData();
        if (/* 验证不通过条件 */)
        {
            results.Add(new ValidationResult("验证失败的提示信息"));
        }
        
        return results;
    }
}

方案2:使用异步验证(适用于异步服务方法)

如果服务方法是异步的(如GetIdAsync),实现IAsyncValidatableObject接口来进行异步验证:

public partial class Dto : IAsyncValidatableObject
{
    public async Task<IEnumerable<ValidationResult>> ValidateAsync(ValidationContext validationContext, CancellationToken cancellationToken)
    {
        var results = new List<ValidationResult>();
        
        var scService = validationContext.GetService(typeof(ISCService)) as ISCService;
        if (scService == null)
        {
            results.Add(new ValidationResult("无法获取ISCService服务"));
            return results;
        }
        
        var site = await scService.GetIdAsync(/* 传入待验证的ID参数 */);
        if (site == null)
        {
            results.Add(new ValidationResult("该ID不存在"));
        }
        
        return results;
    }
}

方案3:自定义验证属性(拆分验证逻辑)

如果单个字段的验证需要服务,可以创建自定义ValidationAttribute,在属性内部通过ValidationContext获取服务:

public class IdExistsAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var scService = validationContext.GetService(typeof(ISCService)) as ISCService;
        if (scService == null)
        {
            return new ValidationResult("无法获取ISCService服务");
        }
        
        var id = value as string;
        if (string.IsNullOrEmpty(id))
        {
            return new ValidationResult("ID不能为空");
        }
        
        // 同步服务方法调用示例
        var site = scService.GetId(id);
        if (site == null)
        {
            return new ValidationResult("该ID不存在");
        }
        
        return ValidationResult.Success;
    }
}

在DTO中使用该属性:

public partial class Dto
{
    [IdExists]
    public string Id { get; set; }
}

注意:如果服务方法是异步的,自定义验证属性需要结合异步验证逻辑实现,建议优先使用IAsyncValidatableObject方案。

内容的提问来源于stack exchange,提问作者Mukesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 23:00:25