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を参照する必要があります。

Unityを使用して正しいバリデーターをフックする他の解決策はありますか?

インターフェース

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;
}

1つの特定のバリデーター:

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                
        }
    }
}

Unity登録:

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

よろしくお願いします

4

2 に答える 2

2

次の 2 つのことを行うことができます。

  1. Unity コンテナーを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.ServiceLocationservicelocator はアンチパターンであると常に考えています。

于 2013-03-04T13:17:13.817 に答える