J'ai une interface pour implémenter un "formateur de sortie" qui ressemble un peu à ceci:
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
est donc conservé dans une base de données via Dapper et sa propriété OutputType
est stockée sous forme de valeur entière sous-jacente (c'est-à-dire dans une colonne INT
). Comme vous pouvez le deviner, je veux fournir une instance d'un IFormatOutput
pour gérer un SomeFormattableEntity
basé sur sa propriété OutputType
.
Existe-t-il une manière propre et efficace de gérer ce type de relation? Mes idées jusqu'à présent incluent une usine avec des entrailles potentiellement composé de:
Je me rends compte qu'il n'est pas souhaitable d'exiger une instance d'une chose dont le type est basé sur une valeur, mais il semble difficile d'éviter cela lorsque SQL est impliqué. Fondamentalement, le problème est que plusieurs «choses» qui ont tous des types .NET différents sont stockées dans une seule table. Je continue à courir dans cet idiome et je suis incapable de trouver une solution élégante.
Je choisirais probablement un attribut personnalisé avec une propriété FormatsOutputFor. IFormatOutput
ensuite toutes vos implémentations d' IFormatOutput
avec l'attribut. par exemple
[YourAttribute(OutputFormat.Html)]
public class HtmlOutputFormatter : IFormatOutput {}
Puis dans votre usine:
// 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>
Vous souhaitez probablement créer un cache interne qui mappe une valeur OutputFormat
sur un Type
. Ensuite, votre usine peut vérifier que vous avez uniquement un type mappé sur chaque format de sortie et si vous essayez d'obtenir un formateur pour une valeur d'énumération qui n'a pas de classe correspondante, vous n'obtiendrez pas une exception TypeLoadException obscure de la part de l'activateur.
J'espère que cela a du sens ...
Que diriez-vous:
OutputFormat format = OutputFormat.Excel;
object obj = Activator.CreateInstance("myAssemblyName", format.ToString());
En supposant que les éléments de votre enum ont le nom exact de vos types?