0

我正在为一个实体使用 CustomValidation,并且我想在其中注入 Repository。验证方法必须是静态的。除了服务位置之外,还有什么方法可以在静态上下文中注入对象?

这是我的元数据:

[MetadataTypeAttribute(typeof(BillPosition.BillPositionsMetadata))]
[CustomValidation(typeof(BillPositionValidator), "ValidateBillPositionsCount")]
public partial class BillPosition
{
    internal sealed class BillPositionsMetadata
    {
        private BillPositionsMetadata() { }

        public int BillId { get; set; }
    }
}

这是验证器代码:

public class BillValidator
{
    [Inject]
    public static IRepository Repository { get; set; }

    public static ValidationResult ValidateBillPositionsCount(BillPosition bill, ValidationContext context)
    {
        ValidationResult result = ValidationResult.Success;

        /* Repository wasn't injected and I get null reference exception */
        var billPositions = Repository.BillPositions.Count(position => position.BillId == bill.BillId);
        if (bill.BillPositions.Count == 0 && billPositions == 0)
        {
            result = new ValidationResult("Invalid positions count", new[] { "BillPositions" });
        }

        return result;
    }
}
4

3 回答 3

0

没有任何方法可以注入自定义验证器。服务定位器或某种形式的反射可用于访问正在执行验证器的实例上的属性或方法。您可以通过 ValidationContext 访问此实例。

http://www.jaltiere.com/index.php/2010/05/04/ninject-with-mvc-and-validationattributes/

于 2013-10-12T21:21:45.393 回答
0

您可以只调用 IoC 并解决依赖关系。就像我使用 Unity 一样。在这些情况下,我会调用 Bootstrapper.Unity.Resolve("NameOfMyDependency")

于 2013-10-12T23:12:17.880 回答
0

如果您没有从依赖注入容器中解析验证器,您仍然可以使用某种服务定位器直接解析存储库:

public class BillValidator
{
    static BillValidator()
    {
        Repository = ServiceLocator.Current.GetInstance<IRepository>();
    }

    public static IRepository Repository { get; set; }
}

这样,您可以使用new-keyword 初始化验证器:

var validator = new BillValidator();

而且您仍然可以在验证器中解决依赖关系。

由于存储库在类型初始化程序中得到解析,因此在您的应用程序中,每种类型仅执行一次。验证器的所有实例都将使用相同的存储库。

此代码在使用 Unity 时有效,但在使用 MEF 或其他容器时应该是等效的。

于 2013-10-18T09:54:00.547 回答