2

私は親切に私を負担するためにプログラミングに不慣れです。私はcシャープ、.net 4、VS 2010を使用しています

IHandlermethod で呼び出されるインターフェイス クラスがありますIsValidate()。のようなメッセージがAMOUNT 50 22.4ありAMOUNTます。したがって、メッセージの形式は のようFLOW 12 33 23.1になります。また、FLOWは識別子です。

現在、識別子に基づいて、次のようなさまざまなクラスがあります(さまざまなメッセージ形式とシーケンスを検証する必要があるため、このような約15〜20のクラスがあります)

  1. AmountValidator

  2. FlowValidator

これらのクラスでは、これらがクラスを実装するため、IsValidate()メソッドの実装がありIHandlerます。

私の質問は、メッセージの識別子を特定したら、AMOUNTまたはFLOWクラスのインスタンスを作成したいということです。

これを行う最善の方法は何ですか?( if else ステートメントで 30 個のインスタンスを作成したくありません)

どんな助けにも感謝します。

4

3 に答える 3

3

次のように実行できます。

IHandler handler = (IHandler)Activator.CreateInstance("assemblyname", "typename");
handler.IsValidate();

アセンブリ名は、ハンドラーがあるプロジェクトのプロパティ ページで確認できます。

ここ:アセンブリ名

また、すべて大文字と小文字が区別されるため、クラスの名前が実際に AmountValidator である場合、typename 引数を AMOUNTValidator にすることはできません。

編集:工場サンプル:

public static class HandlerFactory {
    private static Object factoryLock = new Object();
    private static List<IHandler> handlers = null;

    public static IHandler Gethandler(String type) {
        if (handlers == null) {
            lock (factoryLock) {
                if (handlers == null) {
                    IEnumerable<Type> types = typeof(HandlerFactory).Assembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IHandler)));
                    handlers = types.Select(t => (IHandler)Activator.CreateInstance(t));
                }
            }
        }
        return handlers.Where(h => h.Type == type);
    }
}

public interface IHandler {
    String Type { get; }
    Boolean IsValid(String data);
}
于 2012-07-27T11:35:32.567 に答える
2

バリデーターがステートレスであると仮定して、コンストラクターに一度バリデーターをリストする必要があるファクトリ実装:

    public class HandlerFactory
{
    private Dictionary<string, IHandler> _handlers = new Dictionary<string,IHandler>();

    public HandlerFactory()
    {
        _handlers.Add("AMOUNT", new AmountValidator());
        _handlers.Add("FLOW", new FlowValidator());
    }

    public IHandler Create(string key)
    {
        IHandler result;
        _handlers.TryGetValue(key, out result);
        return result;
    }
}

ReflectionとIoCについて詳しく説明してほしい場合は、お知らせください。それはあなたが辞書を初期化する方法を変えるでしょう。

于 2012-07-27T13:20:44.763 に答える
1

すべてのIHandlerクラスがアプリケーションと同じアセンブリに含まれている場合(プラグインのように動的にロードされない場合)、ファクトリメソッドパターンが適切な選択になる可能性があります。IHandlerこのデザインパターンを使用して、クラスの作成を一元化できます。一方、クラスが実行時にロードされる場合は、 .NETReflectionIHandlerを利用する必要があります。オブジェクトの作成に役立つオープンソースのIoCコンテナーもありますが、それらは少しやり過ぎだと思います。

于 2012-07-27T12:09:54.813 に答える