Мне тяжело с конфигурацией StructureMap. У меня есть ValidationProvider, который принимает Func в качестве фабрики проверки. Мне нужно предоставить это, используя структурную карту, чтобы он знал, какую реализацию Validator (абстрактную) он должен вернуть. Я думаю, вы уже сбиты с толку, так что вот код, чтобы прояснить ситуацию:
public class ValidationProvider : IValidationProvider
{
private readonly Func<Type, IValidator> _validatorFactory;
public ValidationProvider(Func<Type, IValidator> validatorFactory)
{
_validatorFactory = validatorFactory;
}
Как вы можете видеть, поставщик валидации делегирует функциональность для определения того, какая реализация IValidator требуется для validatorFactory. У меня также есть Validator, который реализует IValidator.
public abstract class Validator<T> : IValidator
{
IEnumerable<ValidationResult> IValidator.Validate(object entity)
{
if (entity == null) throw new ArgumentNullException("entity");
return this.Validate((T)entity);
}
protected abstract IEnumerable<ValidationResult> Validate(T entity);
}
Затем у меня есть экземпляр Validator для каждой сущности, требующей проверки, например:
public sealed class BidValidator : Validator<Bid>
{
protected override IEnumerable<ValidationResult> Validate(Bid bid)
{
if (bid.User.HasEnoughCredits(bid.Item.Category.ListingPrice) == false)
yield return new ValidationResult("InsufficientCredits", "Not enough credits.");
if(bid.Item.IsValidBidAmount(bid.Amount) == false)
yield return new ValidationResult("Amount", "Bid amount has to be higher than last posted bid.");
if(bid.User.OwnsItem(bid.Item.Id))
yield return new ValidationResult("InvalidBidder", "User cannot bid on his/her own items.");
}
}
И у меня есть NullValidator, который должен быть по умолчанию, когда нет реализации абстрактного Validator
public sealed class NullValidator<T> : Validator<T>
{
protected override IEnumerable<ValidationResult> Validate(T entity)
{
return Enumerable.Empty<ValidationResult>();
}
}
Так что теперь в StructureMap мне нужно связать вещи вместе, но я не могу заставить его работать ... Вот что я получил:
x.For(typeof(Validator<>)).Use(typeof(NullValidator<>));
x.For<Validator<Bid>>().Use<BidValidator>();
x.For<Validator<Rating>>().Use<RatingValidator>();
x.For<Validator<TopLevelCategory>>().Use<TopLevelCategoryValidator>();
});
Func<Type, IValidator> validatorFactory = type =>
{
var valType = typeof(Validator<>).MakeGenericType(type.GetType());
return (IValidator) ObjectFactory.GetInstance(valType);
};
container.Configure(x => x.For<IValidationProvider>().Use(() => new ValidationProvider(validatorFactory)));
Но строка с надписью return (IValidator) ObjectFactory.GetInstance(valType);
продолжает выдавать это исключение:
Код исключения StructureMap: 202 Нет
Экземпляр по умолчанию, определенный для
PluginFamily
Sharwe.Services.Validation.Validator`1 [[System.RuntimeType,
mscorlib, версия = 4.0.0.0,
Culture = нейтрально,
PublicKeyToken = b77a5c561934e089]],
Sharwe.Services, версия = 1.0.0.0,
Культура = нейтральная, PublicKeyToken = ноль
В любом случае, я мог бы это подключить?
P.S .: если есть более простой способ сделать это, я буду рад узнать об этом. Это не было реализовано мной, мне просто понравилось, и я подумал, что стоит попробовать ...