ASP.NET Core / MVC 6 ViewModel中的依赖注入(DI)

时间:2016-02-20 02:38:39

标签: asp.net asp.net-mvc asp.net-core asp.net-core-mvc

我在使用Constructor Injection的控制器中成功使用了ASP.NET 5 / MVC 6 DI。

我现在有一个场景,我希望我的View Models在实现IValidatableObject时在Validate方法中使用该服务。

ViewModel中的构造函数注入不起作用,因为它们需要默认的无参数构造函数。验证Context.GetService也不起作用。

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        MyService myService = (MyService)validationContext.GetService(typeof(MyService));

总是导致MyService为空。

ASP.NET 4,我将创建ValidatableObjectAdapter,通过DataAnnotationsModelValidatorProvider.RegisterDefaultValidatableObjectAdapterFactory&amp;注册它。然后我可以使用validationContext来对象服务的对象。

我目前正在使用用于ASP.NET 5的DI容器中的构建,将在某个阶段移动到结构图)而不是这应该重要。

我的具体验证是对象的属性(例如,用户名)是唯一的。我想将此测试委托给服务层。

2 个答案:

答案 0 :(得分:5)

自ASP.NET RC2起,[FromServices]已被删除。

如果您希望viewModel中的DI完全用于IValidatableObject.Validate,那么您可以使用validationContext.GetService(type)来获取您的服务。这在RC1中不起作用

EG

MyService myService = (MyService)validationContext.GetService(typeof(myService));

这是一种通用的扩展方法,可以使处理更加愉快。

public static class ValidationContextExtensions
{
    public static T GetService<T>(this ValidationContext validationContext)
    {
        return (T)validationContext.GetService(typeof(T));
    }
}

答案 1 :(得分:1)

感谢@odeToCode的答案。为了完整起见,我将他的评论作为我的(工作)示例的答案重新发布。神奇的是[FromServices]属性。

public class CreateDynamicMappingProfileViewModel : IValidatableObject
{

    [Display(Name = "Name", Order = 1), Required, MaxLength(50, ErrorMessage = "The name field allows a maximum of 50 characters")]
    public string Name { get; set; }

    [Display(Name = "Data Format", Order = 2), Required]
    public DataFormat DataFormat { get; set; }

    [Display(Name = "Data Context", Order = 3), Required]
    public DataContextType DataContextType { get; set; }

    [FromServices]
    public IMappingProfileServices MappingProfileServices { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        IMappingProfile mappingProfile = new DynamicMappingProfile(Name, DataFormat, DataContextType);
        return MappingProfileServices.ValidateCanSave(mappingProfile);
    }
}