2

現在、新しいハンドヘルド ソフトウェアを開発中です。アプリケーションの性質について説明することはできないので、代わりに例を使用します。

私たちは、学校を管理するためのハンドヘルド ソフトウェアを設計しています。システムの各側面をモジュール化して、さまざまな学校がさまざまな機能を使用できるようにしたいと考えています。

私たちのシステムは、メインメニューとログイン画面から始まります。これをシステムのベースにして、モジュールを追加する場所にしたいと思います。つまり、SchoolPda というプロジェクトを作成します。

次に、さまざまなモジュールが必要です。つまり、学生の登録を処理する登録モジュールが必要です。教室の清掃などを管理する教室モジュールが欲しい

これが機能する方法は、さまざまなdllを含める/含めないことと、dllが存在する場合にそれらのモジュールにアクセスするためのボタンをベースシステムのメインメニューに公開することです。それがまさに私たちが求めていることです。

誰かがこのようなことをした経験がありますか? それを行う最良の方法は何ですか?データベースは常に完全なデータベースであるため、データベースについて心配する必要はありませんが、関連するモジュールが存在しない場合、アスペクトは読み込まれません。

4

4 に答える 4

3

私は現在、コンパクト フレームワークとフル フレームワークの両方で動作し、モジュール式に構築されたアプリケーションも開発しています。

私が実装した方法は、dll の場所をスキャンし、各タイプを列挙し、クラスに関する有用な情報を含む "ScreenInfoAttribute" または "WidgetInfoAttribute" が定義されているかどうかを調べることです。

これはスニペットです。これには 3.5 コードが含まれていますが、これは最近 2.0 から切り替えたためですが、原則は 2.0 でも機能します。

public void Analyze(FileInfo file) {
        Assembly asm = Assembly.LoadFrom(file.FullName);
        List<Data.AnyPlugin> types = GetPluginTypes(asm.GetTypes());

        if (types.Count > 0) {
            types.ForEach(x => x.AssemblyPath = file.FullName);
            if (_plugins.ContainsKey(file.FullName)) {
                _plugins[file.FullName].Plugins.AddRange(types);
            } else {
                AssemblyPlugin asp = new AssemblyPlugin();
                asp.Ass = asm;
                asp.Plugins = types;
                _plugins.Add(file.FullName, asp);
            }
        }
    }

    private List<Data.AnyPlugin> GetPluginTypes(Type[] types) {
        List<Data.AnyPlugin> returnTypes = new List<AnyPlugin>();
        foreach (Type t in types) {
            Data.AnyPlugin st = GetPluginType(t);
            if (st != null) returnTypes.Add(st);
        }
        return returnTypes;
    }

    private Data.AnyPlugin GetPluginType(Type type) {
        if (type.IsSubclassOf(typeof(Screens.bScreen<T>))) {
            Screens.ScreenInfoAttribute s = GetScreenAttrib(type);
            if (s != null) {
                return new Data.ScreenPlugin("", type, s);
            }
        } else if (type.IsSubclassOf(typeof(Widgets.bWidget<T>))) {
            Widgets.WidgetInfoAttribute w = GetWidgetAttrib(type);
            if (w != null) return new Data.WidgetPlugin("", type, w);
        }
        return null;
    }

    private Screens.ScreenInfoAttribute GetScreenAttrib(Type t) {
        Attribute a = Attribute.GetCustomAttribute(t, typeof(Screens.ScreenInfoAttribute));
        return (Screens.ScreenInfoAttribute)a;
    }
于 2009-01-06T10:16:14.423 に答える
3

私はそれを2つの方法で行ったプロジェクトに参加しました:

  • あるプロジェクトでは、顧客がライセンスを受けていない場合、特定の DLL を展開しませんでした。それがあなたが提案していることです。うまくいきました。もちろん、追加のインストールなしでこれらのモジュールを有効にする方法はありませんでしたが、そのアプリには完全に理にかなっています。

  • 別のプロジェクトでは、すべてを展開し、顧客がライセンスを取得したメニュー、ボタンなどのみをエンド ユーザーに公開しました。これは、ユーザーがライセンスを追加することで追加のモジュールを簡単に追加できるためです。ライセンスが追加されると、次のログイン時にそれらが魔法のように表示されました。

したがって、私の経験では、ライセンス モデルを意思決定の 1 つの大きな要素と見なすことをお勧めします。これらの余分なモジュールをその場で追加したいかどうかを考えてみてください。

于 2009-01-06T10:09:09.930 に答える
0

CLRで機能するかどうかはわかりませんが、dll /モジュールを検出してロードする方法を作成するために、MEFを見てください。また、メイン メニューにボタンを追加できるように、必要な情報を取得する GetMenuItem メソッド (またはそのようなもの) をモジュールに持たせることもできます。

明らかに、意味がある場合はメイン メニューに別のデザインを使用してください。あなたのコアを変更します。

これが最大の意味をなさない場合は申し訳ありません。一方向のアイデアを提供したいと思っています。

于 2009-01-06T10:10:08.617 に答える
0

すべてのモジュールに共通のインターフェースを実装させてください。GetButtons() や GetActions() などのメソッドを追加します。

次に、AssemblyName と ClassName に関する情報を構成ファイルに配置できます。指定したアセンブリをロードし、Activator.CreateInstance を使用してクラスのインスタンスを作成し、それをインターフェイスにキャストして、GetButtons() などのメソッドを呼び出すのは簡単です。

于 2009-01-06T12:22:10.443 に答える