C#で文字列識別子に基づいてクラスオブジェクトを作成する
-
12-12-2019 - |
質問
プログラミングは初心者ですので、よろしくお願いします。私はC Sharp、.net 4、VS 2010を使用しています
というインターフェイスクラスがあります IHandler
メソッド付き IsValidate()
。のようなメッセージがあります AMOUNT 50 22.4
, 、 どこ AMOUNT
は識別子です。したがって、メッセージの形式は次のようになります FLOW 12 33 23.1
, 、またどこで FLOW
は識別子です。
さて、識別子に基づいて、次のようなさまざまなクラスがあります(さまざまなメッセージ形式とシーケンスを検証する必要があるため、このようなクラスが約15〜20あります)
AmountValidator
FlowValidator
これらのクラスには次の実装があります IsValidate()
これらが実装するメソッド IHandler
クラス。
さて、私の質問は、次のようなメッセージの識別子を特定したら、 AMOUNT
または FLOW
クラスのインスタンスを作成したいです。
これを行う最善の方法は何ですか?( if else ステートメントで 30 個のインスタンスを作成したくないです)
よろしくお願いします。
解決
次のようにして実行できます。
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);
}
他のヒント
バリデーターがステートレスであると仮定して、コンストラクター内でバリデーターを一度リストする必要があるファクトリー実装:
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コンテナ それはオブジェクトの作成には役立ちますが、少しやりすぎだと思います。