我有一个我想尝试与dto联系的枚举:
public enum DtoSelection
{
dto1,
dto2,
dto3,
}
Run Code Online (Sandbox Code Playgroud)
此枚举中有108个和值.
我为这些dto中的每一个都有一个dto对象:
public class dto1 : AbstractDto
{
public int Id { get; set; }
//some stuff specific to this dto
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建一个方法(最终是一个服务),它将返回一个与所讨论的dto相关联的类型的新dto对象:
private AbstractDto(int id)
{
if (id == DtoSelection.Dto1.ToInt()) //extension method I wrote for enums
return new Dto1();
if (id == DtoSelection.Dto2.ToInt())
return new Dto2();
}
Run Code Online (Sandbox Code Playgroud)
显然我不想这样做108次.无论出于何种原因,我的大脑只是遗漏了一些明显 处理这个问题的最佳方法是什么.
使用Activator.CreateInstance方法并向其传递枚举的ToString值。
Type type = Type.GetType(DtoSelection.dto1.ToString());
var temp = Activator.CreateInstance(type);
Run Code Online (Sandbox Code Playgroud)
只要在与AbstractDto相同的名称空间中定义了Dto类,该类就可以满足您的要求(如果没有,则需要对其进行调整):
给定以下枚举和类:
public enum DtoSelection
{
Dto1,
Dto2,
Dto3,
}
public abstract class AbstractDto
{
}
public class Dto1 : AbstractDto
{
}
public class Dto2 : AbstractDto
{
}
public class Dto3 : AbstractDto
{
}
Run Code Online (Sandbox Code Playgroud)
此方法将解决它们:
public static class DtoFactory
{
public static AbstractDto Create(DtoSelection dtoSelection)
{
var type = Type.GetType(typeof(AbstractDto).Namespace + "." + dtoSelection.ToString(), throwOnError: false);
if (type == null)
{
throw new InvalidOperationException(dtoSelection.ToString() + " is not a known dto type");
}
if (!typeof(AbstractDto).IsAssignableFrom(type))
{
throw new InvalidOperationException(type.Name + " does not inherit from AbstractDto");
}
return (AbstractDto)Activator.CreateInstance(type);
}
}
Run Code Online (Sandbox Code Playgroud)
解决此问题的一种优雅方法是使用属性和一个基类。我来给你展示:
您必须创建一个基类。在您的示例中,可能是 AbstractDto,如下所示:
public abstract class AbstractDto : Attribute
{
//code of AbstractDto
}
Run Code Online (Sandbox Code Playgroud)
然后,我们需要创建一个自定义属性,该属性将在每个 Dto 类上使用,以确定哪个枚举对应于每个类。
public class DtoEnumAttribute : Attribute
{
public DtoSelection Enum { get; set; }
public DtoEnumAttribute(DtoSelection enum)
{
this.Enum = enum;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我们应该用适当的枚举来装饰每个子 Dto。我们以 Dto1 为例:
[DtoEnum(DtoSelection.Dto1)]
public class Dto1 : AbstractDto
{
//code of Dto1
}
Run Code Online (Sandbox Code Playgroud)
最后,您可以使用可以接收特定枚举和过滤器或您需要的任何逻辑的方法。以下代码将实例化从AbstractDto继承的每个类,并按您定义的 Enum 排序。您可以在Where 子句中使用它来仅返回与所需枚举匹配的类的实例。询问我在这一点上您是否需要帮助。
public void MethodToGetInstances()
{
IEnumerable<AbstractDto> dtos = typeof(AbstractDto)
.Assembly.GetTypes()
.Where(t => t.IsSubclassOf(typeof(AbstractDto)) && !t.IsAbstract)
.Select(t => (AbstractDto)Activator.CreateInstance(t))
.OrderBy(x => ((DtoEnumAttribute)x.GetType().GetCustomAttributes(typeof(DtoEnumAttribute), false).FirstOrDefault()).Enum);
//If you have parameters on you Dto's, you might pass them to CreateInstance(t, params)
}
Run Code Online (Sandbox Code Playgroud)
在dtos列表中,您将拥有所需的实例。希望能帮助到你!
| 归档时间: |
|
| 查看次数: |
4444 次 |
| 最近记录: |