0

我需要替换以下行:

var validator = DependencyResolver.Current.GetService<IValidator<T>>();

public class ValidationFactory : IValidationFactory
{
    public void Validate<T>(T entity) where T : class, IEntity
    {
        var validator = DependencyResolver.Current.GetService<IValidator<T>>();

        var result = validator.Validate(entity);

        if (result.Count() > 0)
            throw new BusinessServicesException(result);
    }
}

我需要参考: System.Web.Mvc 才能使其工作。

是否有任何其他解决方案可以使用统一挂钩正确的验证器?

接口

public interface IValidator<T> where T : class, IEntity
{
    IEnumerable<ValidationResult> Validate(T entity);
}

public interface IValidationFactory
{
    void Validate<T>(T entity) where T : class, IEntity;
}

一个特定的验证器:

public class CanCreateOrUpdateUserValidator : IValidator<User>
{
    private readonly IUnitOfWork unitOfWork;

    public CanCreateOrUpdateUserValidator(IUnitOfWork unitOfWork)
    {
        this.unitOfWork = unitOfWork;
    }

    public IEnumerable<ValidationResult> Validate(User entity)
    {
        if (entity == null)
        {
            yield return new ValidationResult("");
        }
        else
        {
            // more logic                
        }
    }
}

统一注册:

container.RegisterType<IValidationFactory, ValidationFactory>(new ContainerControlledLifetimeManager());
container.RegisterType<IValidator<User>, CanCreateOrUpdateUserValidator>(new ContainerControlledLifetimeManager());

最好的祝福

4

2 回答 2

2

你可以做两件事:

  1. 将统一容器注入ValidationFactory构造函数。但是,由于不应从任何较低层引用 Unity,这意味着ValidationFactory应将实现移动到Composition Root中。考虑到此类中的少量代码,这应该不是问题。

  2. 与其注入 Unity 容器,不如注入一个Func<Type, object>允许为您创建IValidator<T>实现的委托。当您注册时,您提供一个使用此委托在现场启动IValidationFactory的单个ValidationFactory实例:new

container.RegisterInstance<IValidationFactory>(
    new ValidationFactory(type => container.Resolve(type)));

Unity 不包含任何开箱即用的批量注册工具,因此您必须手写验证器的批量注册。然而,Unity 确实允许您将开放的通用接口映射到开放的通用实现,如下所示:

container.RegisterType(
    typeof(IValidator<>),
    typeof(NullValidator<>));

这允许您始终返回一个验证器,并且它使验证工厂不必检查给定的验证器是否存在T

于 2013-03-04T22:23:20.930 回答
0

您可以使用创建服务定位器Microsoft.Practices.ServiceLocation

    //on init app
    Dim container As IUnityContainer = New UnityContainer()
    container.RegisterType<IValidationFactory, ValidationFactory>(new ContainerControlledLifetimeManager());
    container.RegisterType<IValidator<User>, CanCreateOrUpdateUserValidator>(new ContainerControlledLifetimeManager());
    Dim provider = New UnityServiceLocator(container)
    ServiceLocator.SetLocatorProvider(Function() provider)

在您的 ValidatorFactory 中:

var validator = ServiceLocator.Current.GetInstance<IValidator<T>>();//returns configured class

但这会产生依赖Microsoft.Practices.ServiceLocation,我一直认为 servicelocator 是一种反模式。

于 2013-03-04T13:17:13.817 回答