3

ポータブル ライブラリ クラスでドメイン オブジェクトを作成しています。それらは実装する必要がINotifyPropertChangedあり、INotifyDataErrorInfo

したがって、私のドメインクラスはこの基本クラスを実装する必要があります

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 を作成できません。新しいものを作成するにはどうすればよいですか?

UPDATE 私のインテリセンスによると、これには含まれています。

#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);
    }
}
4

1 に答える 1

4

これは私たちが見逃したものです。Visual Studio 2012 の初期のビルドでは、Windows ストア アプリから削除されたため、IServiceProvider を使用できませんでした。これは、ポータブルがその下でモデル化された方法により、他のプラットフォームの組み合わせもそれを公開できないことを意味しました. これにより、それに依存するものはすべて削除されたため、ValidationContext コンストラクターが作成されました。後で IServiceProvider を追加し直しましたが、このコンストラクターがありませんでした。内部でバグを報告しましたが、将来のバージョンで再度追加できるかどうかを確認します。

これを回避するには、いくつかのオプションがあります。

1) .NET Framework 4.5 および Silverlight 5 をターゲットにします。これらのバージョンでは、IServiceProvider に依存しない新しいコンストラクターが追加されました。

2) リフレクションを使用してコンストラクターを呼び出します。これは .NET Framework と Silverlight でのみ機能することに注意してください。このコンストラクターを公開しないため (InvalidOperationException がスローされます)、Windows ストア アプリでは機能しません。

3) プラットフォーム固有のプロジェクト (つまり、.NET Framework 4.0 または Silverlight 4) プロジェクトで ValidationContext 自体を作成し、それをポータブル ライブラリに挿入します。これは、ある種の依存性注入を介して行うか、 「既存のライブラリを PCL に変換する」セクションの「ポータブル クラス ライブラリを使用して継続的なクライアントを作成する」で説明したプラットフォーム アダプター パターンを介して行うことができます。

于 2012-10-08T21:40:09.413 に答える