質問

質問 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()); 

質問:

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

解決

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つのオプションは、ラップされているクラスと同じインターフェイスを実装するクラスを生成することです。これにはWebには多くの例があります。主な要件はあなたのものです Customer どちらかが必要です interface または、すべてのプロパティが仮想である必要があります。

他のヒント

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

私はそれを使用したことがありませんが、あなたはおそらくこのようなものを使用することができます postsharp.

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

私の意見では、これは提案されているIOCコンテナソリューションを使用するよりも厄介です。ただし、リンクされた質問で議論されていたように、一般的な解決策として適用されることはありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top