Ah, I see what you mean. When you said that you wanted to integrate with FluentValidation, I assumed you meant that you wanted to replace the default error messages.
What you want is certainly possible - each rule has an IStringSource associated with it that is used to load the error message. You can write a custom IStringSource implementation and then associate it with the rule (via an extension method would be the simplest thing). Here's a simplistic example:
public class TranslationServiceStringSource : IStringSource { private string _text; private ITranslatorService _translator; public TranslationServiceStringSource(string text) { _text = text; // get a reference to the translator service // If you're using an IoC container then you could grab it from the container at this point. _translator = new TranslatorService(); } public string GetString() { string culture = Thread.CurrentThread.CurrentUICulture.Name; return _translator.Get(_text, culture); } public string ResourceName { get { return null; } } public Type ResourceType { get { return null; } } } public static class MyFluentValidationExtensions { public static IRuleBuilderOptions<T, TProperty> Translate<T, TProperty>(this IRuleBuilderOptions<T, TProperty> rule, string text) { return rule.Configure(config => { config.CurrentValidator.ErrorMessageSource = new TranslationServiceStringSource(text); }); } }
...you can then use it like this:
public class PersonValidator : AbstractValidator<Person> { public PersonValidator() { RuleFor(x => x.Surname).NotNull().Translate("Surname required"); } }