为什么在Portable Library类中我无法实例化ValidationContext以及如何修复它?

时间:2012-10-06 17:25:37

标签: c# mvvm inotifypropertychanged portable-class-library inotifydataerrorinfo

我在可移植库类中创建了我的域对象。那些人应该实施INotifyPropertChangedINotifyDataErrorInfo

因此,我的域类应该实现这个基类

public abstract class DomainObject : INotifyPropertyChanged, INotifyDataErrorInfo
{
    private ErrorsContainer<ValidationResult> errorsContainer;

    protected DomainObject() {}

    public event PropertyChangedEventHandler PropertyChanged;
    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

    public bool HasErrors
    {
        get { return this.ErrorsContainer.HasErrors; }
    }

    protected ErrorsContainer<ValidationResult> ErrorsContainer
    {
        get
        {
            if (this.errorsContainer == null)
            {
                this.errorsContainer =
                    new ErrorsContainer<ValidationResult>(pn => this.RaiseErrorsChanged(pn));
            }

            return this.errorsContainer;
        }
    }

    public IEnumerable GetErrors(string propertyName)
    {
        return this.errorsContainer.GetErrors(propertyName);
    }

    protected void RaisePropertyChanged(string propertyName)
    {
        this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
    }

    protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        var handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, e);
        }
    }

    protected void ValidateProperty(string propertyName, object value)
    {
        if (string.IsNullOrEmpty(propertyName))
        {
            throw new ArgumentNullException("propertyName");
        }

        this.ValidateProperty(new ValidationContext(this, null, null) { MemberName = propertyName }, value);
    }

    protected virtual void ValidateProperty(ValidationContext validationContext, object value)
    {
        if (validationContext == null)
        {
            throw new ArgumentNullException("validationContext");
        }

        List<ValidationResult> validationResults = new List<ValidationResult>();
        Validator.TryValidateProperty(value, validationContext, validationResults);

        this.ErrorsContainer.SetErrors(validationContext.MemberName, validationResults);
    }

    protected void RaiseErrorsChanged(string propertyName)
    {
        this.OnErrorsChanged(new DataErrorsChangedEventArgs(propertyName));
    }

    protected virtual void OnErrorsChanged(DataErrorsChangedEventArgs e)
    {
        var handler = this.ErrorsChanged;
        if (handler != null)
        {
            handler(this, e);
        }
    }
}

但我意识到这一行

        this.ValidateProperty(new ValidationContext(this, null, null)
           { MemberName = propertyName }, value);

我无法创建ValidationContext对象,因为它没有任何构造函数。如何创建新的?

更新 根据我的Intellisense,它包含。

#region Assembly System.ComponentModel.DataAnnotations.dll, v2.0.5.0
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.0\Profile\Profile46\System.ComponentModel.DataAnnotations.dll
#endregion

using System;
using System.Collections.Generic;

namespace System.ComponentModel.DataAnnotations
{
    // Summary:
    //     Describes the context in which a validation check is performed.
    public sealed class ValidationContext
    {
        // Summary:
        //     Gets or sets the name of the member to validate.
        //
        // Returns:
        //     The name of the member to validate.
        public string DisplayName { get; set; }
        //
        // Summary:
        //     Gets the dictionary of key/value pairs that is associated with this context.
        //
        // Returns:
        //     The dictionary of the key/value pairs for this context.
        public IDictionary<object, object> Items { get; }
        //
        // Summary:
        //     Gets or sets the name of the member to validate.
        //
        // Returns:
        //     The name of the member to validate.
        public string MemberName { get; set; }
        //
        // Summary:
        //     Gets the object to validate.
        //
        // Returns:
        //     The object to validate.
        public object ObjectInstance { get; }
        //
        // Summary:
        //     Gets the type of the object to validate.
        //
        // Returns:
        //     The type of the object to validate.
        public Type ObjectType { get; }

        // Summary:
        //     Returns the service that provides custom validation.
        //
        // Parameters:
        //   serviceType:
        //     The type of the service to use for validation.
        //
        // Returns:
        //     An instance of the service, or null if the service is not available.
        public object GetService(Type serviceType);
    }
}

1 个答案:

答案 0 :(得分:4)

这是我们错过的。在Visual Studio 2012的早期版本中,IServiceProvider由于从Windows应用商店应用中删除而无法使用。由于便携式在其下方建模的方式,这意味着没有其他平台组合可以暴露它。这导致任何依赖于它的东西被删除,因此ValidationContext构造函数。后来我们又添加了IServiceProvider,并错过了这个构造函数。我在内部提交了一个错误,我们会看看是否可以在将来的版本中重新添加它。

要解决此问题,您有几个选择:

1)目标.NET Framework 4.5和Silverlight 5.这些版本添加了新的构造函数,它们不依赖于IServiceProvider。

2)使用Reflection调用构造函数。请注意,这只适用于.NET Framework和Silverlight。它在Windows应用商店应用中不起作用,因为它不公开此构造函数(它将抛出InvalidOperationException)。

3)让特定于平台的项目(即.NET Framework 4.0或Silverlight 4)项目自己创建ValidationContext,并将其注入可移植库。您可以通过某种依赖注入,或通过我在{strong> 将现有库转换为PCL 下的Create a Continuous Client Using Portable Class Libraries中调用的平台适配器模式来执行此操作部分。