C#:整数型のEnum値に基づいて型のインスタンスを作成する

c# dapper

質問

私は "出力フォーマッタ"を実装するためのインターフェイスを持っていますが、このような感じです:

public interface IFormatOutput {}
public class HtmlOutputFormatter : IFormatOutput {}
public class TextOutputFormatter : IFormatOutput {}
// etc, etc...

public enum OutputFormat {
    Html,
    Text,
    HappyMeal,
    Excel
}

public class SomeFormattableEntity {
    int Id { get; set; }
    OutputFormat OutputType { get; set; }
}

そのため、 SomeFormattableEntityはDapperを介してデータベースにOutputTypeされ、そのOutputTypeプロパティは基礎となる整数値として(つまりINT列に)格納されます。あなたが推測できるように、 IFormatOutputインスタンスをIFormatOutputして、 OutputTypeプロパティに基づいてIFormatOutputを処理しSomeFormattableEntityOutputTypeます。

このタイプの関係を処理するためのクリーンなベストプラクティスの方法がありますか?これまでの私のアイデアには、

  1. おじいちゃんの恐ろしい醜いスイッチの声明
  2. enum値をTypeにマップする配列
  3. リフレクションベースのマジックマッピングenumメンバ名を文字列として他の場所のクラス型に変換する
  4. 属性を含むマッピングメカニズム

値に基づいた型のインスタンスを必要とすることは望ましくありませんが、SQLが関与している場合はこれを避けるのが難しいようです。基本的には、さまざまな.NETタイプを持つ複数の「もの」が1つのテーブルに格納されるという問題があります。私はこのイディオムに走り続けており、上品な解決策を見つけることができません。

受け入れられた回答

私はおそらく、FormatsOutputForプロパティでカスタム属性に行くだろう。次に、 IFormatOutputすべての実装を属性でIFormatOutputます。例えば

[YourAttribute(OutputFormat.Html)]
public class HtmlOutputFormatter : IFormatOutput {}

あなたの工場では:

// get all your formatters
var formatters = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(s => s.GetTypes())
    .Where(p => Attribute.IsDefined(p, typeof(YourAttribute)));

// Now go through each formatter and use the attribute to figure out which
// output format it's for. Add these to some static IDictionary<OutputFormat, Type>

OutputFormat値をTypeマップする内部キャッシュを構築したいと思うかもしれません。あなたの工場では、各出力形式に1つの型しかマップされていないことを再確認できます。また、対応するクラスを持たない列挙型値のフォーマッタを取得しようとすると、アクティベータから不明なTypeLoadExceptionが発生します。

うまくいけば意味がある...


人気のある回答

どのように:

OutputFormat format = OutputFormat.Excel;
object obj = Activator.CreateInstance("myAssemblyName", format.ToString());

あなたのenumの要素があなたの型の正確な名前を持っていると仮定しますか?



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow