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

问题描述:

我已使用构造函数注入在控制器中成功使用ASP.NET 5/MVC 6 DI.

I'm successfully using ASP.NET 5/MVC 6 DI in my controllers using Constructor Injection.

我现在有一个场景,我希望我的视图模型在实现IValidatableObject时在Validate方法中对服务进行优化.

I now have a scenario where I want my View Models to utalise a service in the Validate method when implementing the IValidatableObject.

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

Constructor injection in the ViewModel does not work because they need a default parameterless constructor. Validation Context.GetService does not work either.

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

总是导致MyService为空.

always results in MyService being null.

ASP.NET 4,我将创建ValidatableObjectAdapter,并通过DataAnnotationsModelValidatorProvider.RegisterDefaultValidatableObjectAdapterFactory&进行注册.那么我可以使用validateContext来引用对服务的引用.

ASP.NET 4, I would create ValidatableObjectAdapter, register it via DataAnnotationsModelValidatorProvider.RegisterDefaultValidatableObjectAdapterFactory & then I could use the validationContext to object references to services.

我目前正在使用ASP.NET 5的内置DI容器,在某个阶段将移至structuremap),但这并不重要.

I'm currently using the build in DI container for ASP.NET 5, will move to structuremap at some stage) not that this should matter.

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

My specific validation is that an object's property (eg, user name) is unique. I want to delegate this test to the service layer.

从ASP.NET RC2开始,[FromServices]已被删除.

As of ASP.NET RC2, [FromServices] has been removed.

如果只想在viewModels中直接为IValidatableObject.Validate提供DI,则可以使用validationContext.GetService(type)来获取服务.这在RC1中不起作用

If you want DI in your viewModels purely for IValidatableObject.Validate then you can use validationContext.GetService(type) to get your service. This did not work in RC1

EG

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

这里是一种通用的扩展方法,使它处理起来更加令人愉快.

Here is a generic extension method to make that a little more pleasant to deal with.

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