22

IoC コンテナーの有用性についての質問で、受賞者は、IoC コンテナーを使用すると次のことができると述べました。

public class UglyCustomer : INotifyPropertyChanged
{
    private string _firstName;
    public string FirstName
    {
        get { return _firstName; }
        set
        {
            string oldValue = _firstName;
            _firstName = value;
            if(oldValue != value)
                OnPropertyChanged("FirstName");
        }
    }

    private string _lastName;
    public string LastName
    {
        get { return _lastName; }
        set
        {
            string oldValue = value;
            _lastName = value;
            if(oldValue != value)
                OnPropertyChanged("LastName");
        }
    }
}

これに:

var bindingFriendlyInstance = IoC.Resolve<Customer>(new NotifyPropertyChangedWrapper()); 

質問:

  • このメリットを提供する魔法の IC コンテナーはどれですか?
  • これを実装する例は?
  • 欠点はありますか?
  • 複雑な依存関係を持つプロジェクトで、これらのオブジェクトにデータ バインディングを適用しようとすると泣くことがありますか?
4

4 に答える 4

9

2 番目のコード スニペットを機能させるには、NotifyPropertyChangedWrapperリフレクション (またはdynamic) を使用して、互換性のあるインターフェイスを提供しCustomer、自動プロパティ通知を実装するクラスを生成する必要があります。データ バインディングの問題はないはずですが、オーバーヘッドが少し発生します。

動的オブジェクトを使用する単純化された実装は、次のようになります。

public class NotifyPropertyChangedWrapper<T> 
    : DynamicObject, INotifyPropertyChanged
{
    private T _obj;

    public NotifyPropertyChangedWrapper(T obj)
    {
        _obj = obj;
    }

    public override bool TryGetMember(
        GetMemberBinder binder, out object result)
    {
        result = typeof(T).GetProperty(binder.Name).GetValue(_obj);
        return true;
    }

    // If you try to set a value of a property that is
    // not defined in the class, this method is called.
    public override bool TrySetMember(
        SetMemberBinder binder, object value)
    {
        typeof(T).GetProperty(binder.Name).SetValue(_obj, value);
        OnPropertyChanged(binder.Name);
        return true;
    }

    // Implement OnPropertyChanged...
}

明らかに、これらのオブジェクトのいずれかを使用するコードは、静的タイプ セーフを失います。もう 1 つのオプションは、ラップされるクラスと同じインターフェイスを実装するクラスを生成することです。これについては、ウェブ上に多くの例があります。主な要件は、 である必要がCustomerあるか、interfaceすべてのプロパティが仮想である必要があるということです。

于 2010-12-14T02:28:52.210 に答える
3

これを一般的な方法 (つまり、任意のクラスに INotifyPropertyChanged を実装する単一のコード) で行うには、プロキシを使用します。Castle.DynamicProxyまたはLinFuまたはUnityでこれを行うための実装がたくさんあります。これらのプロキシ ライブラリは、IoC コンテナーで適切にサポートされています。たとえば、DynamicProxy は Castle Windsor と適切に統合されており、Unity インターセプト (またはそれが何と呼ばれていても) は明らかに Unity コンテナーと適切に統合されています。

于 2010-12-14T05:00:14.907 に答える
3

バインド可能なオブジェクトを自動生成するための特定のソリューションを探している場合は、PropertyChanged.Fody (以前の NotifyPropertyWeaver) を参照する必要があります。これは、INotifyPropertyChanged を実装するクラスを書き換えて、通知コードを含めます。github ページに例があります。

私の意見では、これは提案された IOC コンテナー ソリューションを使用するよりも優れています。ただし、これは INotifyPropertyChanged バインディングに固有のライブラリであるため、リンクされた質問で説明されているように、一般的な解決策としては適用できません。

于 2013-07-02T10:08:20.543 に答える
2

私はそれを使用したことはありませんが、PostSharpを使用してこのようなものを作成できると思われます。

于 2010-12-14T02:28:40.147 に答える