我在使用StructureMap配置时遇到了困难。我有一个ValidationProvider接受一个Func作为其验证工厂。我需要使用结构映射来提供它,以便它知道它应该返回什么Validator(abstract)的实现。我猜你已经很困惑,所以这里有一些代码可以解决问题:
public class ValidationProvider : IValidationProvider
{
private readonly Func<Type, IValidator> _validatorFactory;
public ValidationProvider(Func<Type, IValidator> validatorFactory)
{
_validatorFactory = validatorFactory;
}
如您所见,验证提供程序委派了确定validatorFactory所需的IValidator实现的功能。我也有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 No. 为。定义的默认实例 PluginFamily Sharwe.Services.Validation.Validator`1 [System.RuntimeType, mscorlib,版本= 4.0.0.0, 文化=中性, 公钥= b77a5c561934e089]] Sharwe.Services,版本= 1.0.0.0, Culture = neutral,PublicKeyToken = null
任何方式我都可以搞定这个?
P.S:如果有更简单的方法,我会很高兴知道这件事。这不是我实现的,我只是喜欢它,并且认为值得一试......答案 0 :(得分:2)
更改以下代码:
Func<Type, IValidator> validatorFactory = type =>
{
var valType = typeof(Validator<>).MakeGenericType(type.GetType());
return (IValidator) ObjectFactory.GetInstance(valType);
};
要:
Func<Type, IValidator> validatorFactory = type =>
{
var valType = typeof(Validator<>).MakeGenericType(type);
return (IValidator) ObjectFactory.GetInstance(valType);
};
您正在提供Type
参数并致电type.GetType()
,该Type
会返回Type
的{{1}}个实例...呃......还在跟着我吗?异常消息实际上说明了一切:
未定义默认实例 验证器; System.RuntimeType&GT;
答案 1 :(得分:1)
我认为问题是ObjectFactory和你创建的Container对象的混合使用......
ObjectFactory创建并管理容器实例,因此如果您创建另一个容器,它们将具有不同的配置。
如果只使用容器对象或仅使用ObjectFactory,它应该可以工作。