2010-10-13 51 views
0

Je reçois une 'erreur non enregistrée' lors de l'exécution de l'appel ValidatorFactory.CreateInstance. Il semble que le type envoyé dans la méthode est correct.Autofac avec FluentValidation dans MVC2

Mon code d'enregistrement:

... 
builder.RegisterAssemblyTypes(assembly).Where(t => t.Name.EndsWith("Validator")).As<IValidator>(); 
builder.Register(d => _containerProvider).As<IContainerProvider>(); 
builder.Register(d => new ValidatorFactory(_containerProvider.ApplicationContainer.Resolve<IContainerProvider>())).As<IValidatorFactory>(); 

_containerProvider = new ContainerProvider(builder.Build()); 

Code Mon ValidatorFactory:

public class ValidatorFactory : ValidatorFactoryBase { 
    private readonly IContainerProvider _containerProvider; 

    public ValidatorFactory(IContainerProvider containerProvider) { 
     _containerProvider = containerProvider; 
    } 

    public override IValidator CreateInstance(Type validatorType) { 
     return _containerProvider.ApplicationContainer.Resolve<IValidator>(validatorType); 
    } 
} 

Mon modèle de vue et validateur de code:

[Validator(typeof(EmployeeViewModelValidator))] 
public class EmployeeViewModel { 
    public EmployeeViewModel() {} 
    public EmployeeViewModel(string firstName) { 
     FirstName = firstName; 
    } 

    public string FirstName { get; private set; } 
} 

public class EmployeeViewModelValidator : AbstractValidator<EmployeeViewModel> { 
    public EmployeeViewModelValidator() { 
     RuleFor(x => x.FirstName) 
      .NotEmpty(); 
    } 
} 

Ma meilleure estimation est que je suis l'enregistrement de la validateurs faux.

Répondre

0

Code d'enregistrement actuel:

builder.RegisterType<EmployeeViewModelValidator>().Keyed<IValidator>(typeof(EmployeeViewModel)); 
builder.RegisterType<ValidatorFactory>().As<IValidatorFactory>(); 

_containerProvider = new ContainerProvider(builder.Build()); 

actuelle ValidatorFactory:

public class ValidatorFactory : ValidatorFactoryBase { 
    readonly IIndex<Type, IValidator> _validators; 

    public ValidatorFactory(IIndex<Type, IValidator> validators) { 
     _validators = validators; 
    } 

    public override IValidator CreateInstance(Type validatorType) { 
     return _validators[validatorType]; 
    } 
} 

même erreur à l'intérieur CreateInstance :

Le service demandé 'FluentValidation.IValidator`1 [.EmployeeViewModel] (FluentValidation.IValidator)' n'a pas t été enregistré.

+0

dans votre enregistrement, je crois qu'il devrait être 'typeof (EmployeeViewModelValidator)' puisque ce serait le type passé à 'CreateInstance' –

1

Pour résoudre de plusieurs classes qui implémentent IValidator, le autofac documentation montre quelques techniques. Je ne pense pas que vous pouvez utiliser l'analyse d'assemblage avec ces méthodes; vous devrez enregistrer les validateurs individuellement.

Par Nom

builder.RegisterType<EmployeeViewModelValidator>().Named<IValidator>("employee"); 

var r = container.Resolve<IValidator>("employee"); 

Par clé

La documentation montre une énumération utilisée comme une clé, mais vous pouvez utiliser le type comme la clé, qui vous permettent de faire appel Resolve en utilisant le validatorType étant transmis à vous dans la méthode CreateInstance.

builder.RegisterType<EmployeeViewModelValidator>().Keyed<IValidator>(typeof(EmployeeViewModelValidator));  

var r = container.Resolve<IValidator>(validatorType); 

Remarque: La documentation concerne la version 2.3 d'Autofac. J'utilise 2.2.4, ce qui explique pourquoi les noms de méthodes ci-dessus varient de la documentation.

Espérons que cela aide.

+0

La raison du changement de nom est reflétée dans ce scénario - 'Resolve (validatorType)' est trompeur, car 'validatorType' est une clé plutôt que le type de service. Par conséquent, dans 2.3 ceci est 'ResolveKeyed (validatorType)' :) ... bonne réponse! –

+0

@Nicholas Blumhardt, merci et merci pour Autofac :) –

+0

Merci pour la réponse! Voir ci-dessous encore des erreurs. – Mike

1

L'autre réponse par @adrift est une bonne approche propre. Juste pour ajouter quelques notes, cela fonctionne aussi avec le type de relation IIndex<K,V>, qui Autofac fournit automatiquement, par exemple:

public class ValidatorFactory : ValidatorFactoryBase { 
    readonly IIndex<Type, IValidator> _validators; 

    public ValidatorFactory(IIndex<Type, IValidator> validators) { 
     _validators = validators; 
    } 

    public override IValidator CreateInstance(Type validatorType) { 
     return _validators[validatorType]; 
    } 
} 

Note importante: ne pas utiliser IContainerProvider et ApplicationContainer dans un composant — utiliser à la place IComponentContext ou IIndex<K,V> comme ci-dessus. Cela aidera à prévenir les problèmes de vie (votre exemple associe validateurs à l'application plutôt que la durée de vie de la demande.)

+0

Merci pour la réponse! Voir ci-dessous encore des erreurs. – Mike