2010-12-01 19 views
1

私は、構築したいコントロールのフレームワークのコンセプトを持っています。この考え方を変えているのは、私は「1つのサイズがすべてに合っている」アプローチまたは「すべてのものを支配する1つのコントロール」アプローチをとるつもりはないということです。C#でミックスインアーキテクチャフレームワークを構築するには?

例として、Telerikは、ComponentOne、Xceedなどと同様、非常に優れたグリッドコントロールを作成します。しかし、数百または数千のメソッドとプロパティ、複雑なオブジェクトモデルの検索など、すべての巨大なコントロールです。あまりにも頻繁にこれらのグリッドはあなたが必要とするもののために過度の方法ですが、単純なことをするためにグリッド全体を学ぶという難題を乗り越えなければなりません。

私のコンセプトは、より「ミックスイン」なアプローチです。非常にシンプルなコントロールを作成し、コントロールのアラカルトに「アドイン」できる機能を作成します。たとえば、単純なグリッドがあり、グリッドの「セクション」にヘッダとフッタを追加したいとします。

問題はどこですか?このようなことを行う伝統的な方法は、C#がサポートしていない多重継承を使用する方法です。それがサポートされたとしても、MIはそれが解決するよりも多くの問題を追加するという意見はまだ残っています。

私はこの問題に近づく方法について意見を求めています。 MEFは潜在的な解決策でしょうか?

EDIT:私に発生し

何かが、様々な表情からコントロールを構築するために、式ツリーを使用することが可能かもしれないということです。私はこれ以上いくつか考える必要がありますが、それは面白い概念です。

可能な別のオプションは、選択した機能に基づいてアセンブリを生成する「コントロールジェネレータ」です。それはより複雑に見えますが、T4は管理可能かもしれません。

+0

はこちらをご覧ください:http://msdn.microsoft.com/en-us/vcsharp/bb625996.aspx –

+0

@Robertハーヴェイ - 彼らは本当に提供できないので、私はすでに大幅に拡張メソッドを拒否しました追加状態、メソッドのみ。あなたが参照する手法は、私が本当に熱心ではないエンドユーザによるすべての追加状態の実装を必要とするでしょう。 –

答えて

3

いくつかのオプション

  1. Decoratorパターンを考えてみましょう。実行時に構築できるかなりシンプルなクラスの動作を拡張する小さなオブジェクトです。 Dotnetフレームワークの標準的な例は、IOストリーム(StreamReader/Writer、TextStreamReader/Writer、FileStreamReader/Writerなど)の周りにあります。

  2. State、Strategy、Command、およびCompositeパターンは、多くの制御フローを必要とせずにビヘイビアの構成を処理するためのさまざまな選択肢を提供します。たとえば、特定のタイプの動作をオブジェクトの現在の状態に委譲します(いくつかのクラスメソッドは、現在のオブジェクト状態のメソッドを基本的に呼び出します)。ビヘイビアをコマンドオブジェクトに委譲したり、コンポジットコマンドを使用して複雑なコマンドをビルドすることもできます。単一継承は、一般に、継承よりもオブジェクトの合成を優先します。これらはすべて、単一継承で動作するビヘイビアを作成するための古典的なパターンです。

  3. 特定のインスタンスによって動作の一部を実装する必要がある場合、関数プログラミングでは一般的な「中間の穴」パターンの代理人を使用できます。

  4. ポストシャープまたは同様のアスペクト指向プログラミングツールを使用して、実行時またはコンパイル時にビヘイビアを作成することができます。特に、プライマリとはあまり関係のないいくつかの異なるクラスが必要とする動作そのクラスの責任。

1

私はそれが解決する価値のある問題であるかどうかについては言及しないで答えることを試みたいと思います。

これはコンポーネントでは試していませんが、理論的にはDecorator Patternがあります。実行時にプラグインを追加して、コントロール(キーボードとマウス)の入力と(スクリーン)出力を傍受することができます。

+0

私はそれについて考えましたが、デコレーションを実装するために属性を使用している場合、かなり醜いかなり高速になる可能性があり、必要なリフレクションが大幅なパフォーマンスの低下を招くと思います。 –

+0

これはMEFの私の考えでした。しかし、私はこの種のものが実用的かどうかを知るには十分にMEFを知らない。私自身のコード注入方法を開発しなければならないかどうか。 –

1

WPFでは、論理要素のビジュアル表現をデータテンプレートと合成することができます。 Controlクラスは、新しいControlクラスを作成するためにフィーチャーをミキシングするのではなく、コンテンツを配置して視覚化するための豊富なテンプレートシステムを使用して、さまざまなタイプのコンテンツを組み込む機能によって拡張ポイントを提供します。

他の言葉で言えば、おそらく、「それらすべてを支配する1つのコントロール」がありますが、コントロールは完全に柔らかいボディではなくスケルトンです。足場は、フィーチャを追加するための包括的なフレームワークを提供し、テンプレートシステムは、コントロールの部品を洗い出すための接着剤を提供します。


MEFに関して、あなたが購入したのは、拡張コードの発見と注入です。貴重ですが、あなたが説明した問題に直接対処するわけではありません。あなたの問題は、コードの発見とはあまり関係がなく、コヒーレントな全体的なコントロールを作成するためにそのコードがどのように合成されているかのメカニズムと関連しています。 MEFは接着の一部を行うのに役立ちますが、問題の比較的小さい部分です。

+0

それはMEFの良い洞察です。ありがとう、私は分析の実行可能な道を絞り込むために、このようなコメントを期待していた。 –

+0

@Mystere Man、あなたがWPFで全くプレイしていないのなら、それを見てみることをお勧めします。あなたがそれを使用する予定がない場合でも、フレームワークのデザイナーは非常に良いアイデアを取り入れており、カスタムコントロールコードを一切必要とせずに非常に拡張性の高いUIを作成する方法を考えています。それをプレイする場合は、VSデザイナーを使用するのではなく、XAMLを見ることに集中してください。 XAMLは、構成の問題に直接関係するオブジェクトとその関係の簡潔な説明のための非常に強力な言語です。 –

0

フレームワークのアドインタイプを作成したいですか?私は間違いなくManaged Extensibility Frameworkに向けて指摘します。 WinFormsまたはWPFで.Net 4.0で使用できます。

2

個人的には、このようなデザインを実装するには、複数の継承が悪い方法だと思います。多重継承は、ほとんどの場合、悪い設計であるようです。継承はコンポーネント間の関係をはるかに厳格にしています。

構成がはるかに柔軟です。この場合、MEFはこれを開始するのに非常に適しています。

コントロールの基本クラスは、ビヘイビアのコンテナ(基本的にはMEFコンテナ)です。

これは、他のクラスがあなたのコントロールとどのようにやりとりをしているかという問題を残しています。多くのオプションがあります。たとえば、ベースコントロールの標準インターフェイス、メッセージング、またはC#4.0の動的バインディングを使用しています。

+0

私はMIに同意します。私は、これが問題を扱う「伝統的な」方法であると言いました。多分私はMEFをもっと調べなければならないでしょう。私は、より多くの経験を持つ人が、その分析のラインが有益かどうかについてコメントしたいと思っていました。 –

+0

私はWebアプリケーションでかなり軽くMEFを使用しました。私が見てきたことから、それは非常にうまく設計されており、非常に柔軟なコンポーネントのリンクが可能であると言えます。しかし、MEFのプラグイン/スワップ可能な性質とコントロールのマークアップをどのように組み合わせるかを考える必要があります。マークアップを解析するには何かが必要です。このコードでは、マークアップを解析するコントロールについて多くのことを知っている必要があるため、MEFの必要性を否定する可能性があります。 –

0

すでに参照用ミックスインを実装したフレームワークに興味がある場合は、再モーションフレームワーク(https://www.re-motion.org/)の顔をしています。

以下は、「Hello World」レベルのリファレンスアプリケーションです。

webseiteからダウンロードしたアセンブリで、VS2010でクラスライブラリとコンソールアプリケーションを作成し、両方のプロジェクトでassmblies remotion.dllとremotion.interfaces.dllへの参照を追加します。

using System; 

namespace Domain 
{ 
    public class Person 
    { 
    public Person() 
    { 
    } 
    public Person(Person person) 
    { 
     FirstName = person.FirstName; 
     LastName = person.LastName; 
     BirthDay = person.BirthDay; 
    } 

    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public DateTime BirthDay { get; set; } 
    } 
} 



using System; 
using Remotion.Mixins; 

namespace Domain 
{ 
    public interface IEmployeeMixin 
    { 
    int Salary { get; set; } 
    DateTime? HireDate { get; set; } 
    } 

    [Extends(typeof(Person))] 
    public class EmployeeMixin : IEmployeeMixin 
    { 
    public int Salary { get; set; } 
    public DateTime? HireDate { get; set;} 
    public EmployeeMixin() 
    { 
     // set default values 
     Salary = 1000; 
     HireDate = DateTime.Now; 
    } 
    } 
} 



using Domain; 
using Remotion.Reflection; 
using Remotion.Mixins; 

namespace ConsoleApp 
{ 
    class Program 
    { 
    static void Main(string[] args) 
    { 
     Person p = new Person(); 
     p.FirstName = "John"; 
     p.LastName = "Doe"; 

     var employee = (IEmployeeMixin)ObjectFactory.Create<Person>(ParamList.Create(p)); 

     System.Console.WriteLine("Fullname: {0}", ((Person)employee).FirstName + " " + ((Person)employee).LastName); 
     System.Console.WriteLine("Salary: {0}", employee.Salary); 

     System.Console.ReadKey(); 
    } 
    } 
} 

このリファレンス実装に基づいて、このフレームワークでこのミックスインがどのように実装されているかを簡単に知ることができます。このフレームワーク(これは完全なDDD開発フレームワークです)またはmixinsに関する詳細情報を入手したい場合は、お気軽にお問い合わせください。私はより多くの文書をあなたに提供することができます。

ステファン

+0

また、https://www.re-motion.org/communityをチェックしてみることもできます –

関連する問題