为抽象泛型返回适当的具体类型

本文关键字:类型 抽象 泛型 返回 | 更新日期: 2023-09-27 17:52:11

我很难配置StructureMap。我有一个ValidationProvider,它接受一个函数作为它的验证工厂。我需要提供使用结构映射,这样它就会知道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 Exception Code: 202定义的默认实例PluginFamilySharwe.Services.Validation.Validator ' 1 [[System.RuntimeType,= 4.0.0.0 mscorlib,版本,文化=中立,都必须要]],Sharwe。服务、Version = 1.0.0.0文化=中立,都必须空

我能把这个连接起来吗?

p。店员:如果有更简单的方法,我很乐意知道。这不是由我实现的,我只是喜欢它,认为值得一试…

为抽象泛型返回适当的具体类型

修改以下代码:

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(),这将返回该TypeType实例类型…uhhmm . .还在听我说吗?异常消息实际上说明了一切:

没有定义的默认实例Validator

我认为问题是您创建的ObjectFactory和容器对象的混合使用…

ObjectFactory创建并管理一个容器实例,因此如果您创建另一个容器,它们将具有不同的配置。

如果你只使用你的容器对象或只使用ObjectFactory,它应该工作