質問

プログラミングは初心者ですので、よろしくお願いします。私はC Sharp、.net 4、VS 2010を使用しています

というインターフェイスクラスがあります IHandler メソッド付き 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 個のインスタンスを作成したくないです)

よろしくお願いします。

役に立ちましたか?

解決

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

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

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

ここ: assembly name

また、すべて大文字と小文字が区別されるため、クラスの名前が実際に 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);
}

他のヒント

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

    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 について詳しく説明してほしい場合はお知らせください。これにより、辞書の初期化方法が変わります。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top