1

次のような「出力フォーマッタ」を実装するためのインターフェイスがあります。

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プロパティは基になる整数値として(つまり、INT列に)格納されます。ご想像のとおり、プロパティに基づいてIFormatOutputを処理するaのインスタンスを提供したいと思います。SomeFormattableEntityOutputType

このタイプの関係を処理するためのクリーンなベストプラクティスの方法はありますか?これまでの私のアイデアには、次のもので構成される可能性のある内部を備えた工場が含まれています。

  1. おじいちゃんの恐ろしい醜いswitchステートメント
  2. 列挙値を型にマッピングする配列
  3. 他の場所のクラスタイプへの文字列としてのリフレクションベースのマジックマッピング列挙型メンバー名
  4. 属性を含むいくつかのマッピングメカニズム

タイプが値に基づくもののインスタンスを要求することは望ましくないことを私は理解していますが、SQLが関係している場合、これを回避するのは難しいようです。基本的に問題は、すべてがさまざまな.NETタイプを持つ複数の「モノ」が1つのテーブルに格納されることです。私はこのイディオムに出くわし続け、それに対するエレガントな解決策を見つけることができません。

4

2 に答える 2

0

どうですか:

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

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

于 2012-10-30T21:06:58.557 に答える
0

私はおそらくFormatsOutputForプロパティを持つカスタム属性を探します。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が発生しません。

うまくいけば、それは理にかなっています...

于 2012-10-30T22:18:44.317 に答える