Cruft Code。救助へのIOC
-
09-10-2019 - |
質問
の 質問 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コンテナソリューションを使用するよりも厄介です。ただし、リンクされた質問で議論されていたように、一般的な解決策として適用されることはありません。