8

ASP.NET、コンソール アプリ、その他のクラス ライブラリ、Silverlight や WPF などの XAML ターゲットなど、さまざまな状況で使用できるクラス ライブラリを作成しています。

最初に、コレクションを IList として公開することにしました。しかし、XAML を使用してサンプルを作成しているときに、これらのコレクションへのバインドを簡単にしたい場合は、ObservableCollection を使用する必要があることがわかりました。

私のオプションは何ですか?

ライブラリで ObservableCollection を公開し、XAML とは関係のないユーザーにそれを強制することができます。それは悪いことですか?

クラスをジェネリックにして、呼び出し元が ICollection を実装している限り、必要なコレクションの型を指定できるようにすることができます。

ObservableCollection を使用するクラスと、Foo と ObservableFoo を使用しないクラスのセットを作成できます。

クラスに INotifyCollectionChanged を実装することはできますが、ObservableCollection がそれを行うとばかげているように思えます。

明らかに、コードをクリーンでシンプルに保とうとしていますが、データ バインディングをサポートすることは重要なようです。

助言がありますか?

編集:両方の方法を使用してポータブル クラス ライブラリ プロジェクトを作成しようとしました。

私が持っているクラスFooで

    private readonly Collection<string> strings = new Collection<string>();

    public ReadOnlyCollection<string> Strings
    {
        get
        {
            return new ReadOnlyCollection<string>(this.strings);
        }
    }

クラス ObservableFoo で私が持っている

    private readonly ObservableCollection<string> strings = new ObservableCollection<string>();

    public ReadOnlyObservableCollection<string> Strings
    {
        get
        {
            return new ReadOnlyObservableCollection<string>(this.strings);
        }
    }

非常に単純な単体テスト コードは次のとおりです。

    [TestMethod]
    public void TestMethod1()
    {
        var foo = new ObservableFoo(); // or new Foo()

        Assert.AreNotEqual(0, foo.Id);
        Assert.AreNotEqual(0, foo.Strings.Count);
    }

唯一の欠点は、ReadOnlyObservableCollection を使用したときに、テスト プロジェクトでこのコンパイル エラーが発生したことです。

タイプ 'System.Collections.ObjectModel.ReadOnlyObservableCollection`1' は、参照されていないアセンブリで定義されています。アセンブリ 'System.Windows、Version=2.0.5.0、Culture=neutral、PublicKeyToken=7cec85d7bea7798e、Retargetable=Yes' への参照を追加する必要があります。

したがって、この場合、ReadOnlyObservableCollection を使用すると、ユーザーは System.Windows への参照を追加する必要があり、これは欠点です。

編集:ブログに投稿した解決策を思いつきました-ライブラリを移植可能にし、同時にデータバインディングを使いやすくする方法を参照してください。

4

2 に答える 2

3

まあ、それは異なります。純粋なモデルライブラリを作成している場合、WPF固有のインターフェイスを公開することは意味がありません。これにより、必要がない場合でも、ユーザーはWPFライブラリに対してリンクを強制されます。そうでなかったとしても、それはユーザーが必要としない何かを明らかにします、それは良いデザインの私見ではありません。

ライブラリがモデルの使用に限定されていない場合は、いくつかの部分に分割します。すべての使用シナリオに必要なコア、WPF固有のインターフェイスを備えたWPF依存部分、ASP固有の機能を備えたASP固有の部分などです。ユーザーは必要な部品を選んで使用します。


編集:@Julienのコメントが述べているObservableCollection<T>ように、コアの一部になっているため、これを含めると、ユーザーがWPF固有のライブラリに依存することはありません。それにもかかわらず、アイデアは同じままです。WPFを使用する場合、特定の機能(ObservableCollectionINotifyPropertyChanged/ DependencyObject、依存関係のプロパティ、UIスレッドのみの通知など)を提供/操作する必要があることがよくあります。これは、それらがプロジェクトの別個のWPF固有の部分に属していることを意味します。

したがって、ライブラリをいくつかの部分で構成することができます。汎用/モデル開発に必要な関数を含むLibrary.Core.dll、WPF固有のものを処理し、Library.Core.dll、おそらくLibrary.Console.dllを使用するLibrary.WPF.dllおよびLibrary.ASP.dllも同様です。WPFのユーザーはLibrary.Core.dllとLibrary.WPF.dllを使用し、コンソールプログラムにはLibrary.Core.dllとLibrary.Console.dllなどが必要になる場合があります。

于 2012-07-22T14:14:44.170 に答える
3

ライブラリの低レベルのコンポーネントは、APIのさまざまなコンシューマーがそれらを自分の用途に適応させる必要があるかどうかに関係なく、特定の抽象化レベルでそれらのコンポーネントに意味のあるインターフェイスを提供する必要があると思います。

たとえば、複合WPFアプリケーションがコンポーネントを使用する場合、それらのアプリケーションが、コンポーネントによって提供されるIList<T>(またはさらに良いことに)をバインドに適したものに適合させるモデルまたはビューモデルにコンポーネントをカプセル化することは完全に適切です。ビュー。IEnumerable<T>ObservableCollection<T>

コンソールアプリケーションはそのようなオーバーヘッドを必要としない可能性があり、をうまく使用できますIEnumerable<T>

余談ですが、コレクションをとして公開する場合でも注意が必要IList<T>です。これにより、ライブラリの利用者は、たとえば、インターフェイスの精神に合わない可能性のあるアイテムをリストに追加したり、リストから削除したりできます。

于 2012-07-22T14:17:14.650 に答える