我在使用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容器中的构建,将在某个阶段移动到结构图)而不是这应该重要。
我的具体验证是对象的属性(例如,用户名)是唯一的。我想将此测试委托给服务层。
答案 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);
}
}