[英]C#: Create instance of a type based on an integral Enum value
I have an interface for implementing an "output formatter" that looks a bit like this: 我有一个用于实现“输出格式化程序”的接口,看起来像这样:
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; }
}
So SomeFormattableEntity
is persisted in a database via Dapper and its OutputType
property is stored as the underlying integer value (ie, in an INT
column). 因此, SomeFormattableEntity
通过Dapper SomeFormattableEntity
在数据库中,其OutputType
属性存储为基础整数值(即,在INT
列中)。 As you can guess, I want to provide an instance of a IFormatOutput
to handle a SomeFormattableEntity
based on its OutputType
property. 如您所料,我想提供一个IFormatOutput
实例来根据其OutputType
属性处理SomeFormattableEntity
。
Is there some clean best-practice way to handle this type of relationship? 是否有一些干净的最佳做法来处理这种类型的关系? My ideas so far include a factory with innards potentially consisting of: 到目前为止,我的想法包括建立一家具有潜在内部影响的工厂:
I realize it is not desirable to require an instance of a thing whose type is based on a value, but it seems hard to avoid this when SQL is involved. 我意识到,不要求要求其类型基于值的事物的实例,但是在涉及SQL时似乎很难避免这种情况。 Basically the problem is that multiple "things" that all have varying .NET types are stored in a single table. 基本上,问题是所有都具有不同.NET类型的多个“事物”存储在单个表中。 I keep running into this idiom and am unable to find an elegant solution to it. 我一直遇到这个习惯用法,无法找到一种优雅的解决方案。
How about: 怎么样:
OutputFormat format = OutputFormat.Excel;
object obj = Activator.CreateInstance("myAssemblyName", format.ToString());
Assuming the elements of your enum has the exact name of your types? 假设您的枚举的元素具有您类型的确切名称?
I'd probably go for a custom attribute with a FormatsOutputFor property. 我可能会选择带有FormatsOutputFor属性的自定义属性。 Then decorate all of your implementations of IFormatOutput
with the attribute. 然后,使用属性装饰IFormatOutput
所有实现。 eg 例如
[YourAttribute(OutputFormat.Html)]
public class HtmlOutputFormatter : IFormatOutput {}
Then in your factory: 然后在您的工厂中:
// 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>
You probably want to build some internal cache that maps an OutputFormat
value to a Type
. 您可能想要构建一些内部缓存,以将OutputFormat
值映射到Type
。 Then your factory can double check that you have only got one type mapped to each output format and if you try to get a formatter for an enum value that doesn't have a corresponding class then you wont get some obscure TypeLoadException from activator. 然后,您的工厂可以再次检查您是否只有一种类型映射到每种输出格式,如果您尝试为没有对应类的枚举值获取格式化程序,则不会从激活器中得到一些晦涩的TypeLoadException。
Hopefully that makes sense... 希望这是有道理的...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.