(如何)我可以在 C#.Net 中使用反射查询 类 "post-build" 吗?
(How) Can I query classes "post-build", using reflection in C#.Net?
场景:
- 我有一个 visual studio 项目(例如 MyPOCO)中的 .cs 文件列表,其中包含一堆 POCO(普通旧 C# 对象)
- 我必须 运行 一个自定义序列化工具(自制并且我可以访问源代码)将这些 POCO 转换为 XML 文件 - 该工具通过反射完成此操作。
目前,MyPOCOs 项目被标记为 Console App 并且具有如下所示的主要方法:
class Program
{
static void Main(string[] args)
{
//Initialize custom XML Serializer
GenerateBulkVmXML batchSerializer = new GenerateBulkVmXML();
//Add individual POCOs to Serializer
batchSerializer.AddPocoModel(typeof(MyPOCO1), "My.Custom.NameSpace");
batchSerializer.AddPocoModel(typeof(MyPOCO2), "My.Custom.NameSpace1");
batchSerializer.AddPocoModel(typeof(MyPOCO3), "My.Custom.NameSpace2");
//Generate custom XML
batchSerializer .WriteXML();
}
}
每次我们 "run" 上述控制台应用程序时,它都会触发 Main
方法,该方法通过反射查询 POCO classes 并输出 XML。
问题:对于每一个新添加到项目中的POCO,我们都在上面的Main
方法中添加一行调用batchSerializer.AddPocoModel(...)
方法,通过传递他们输入新创建的 POCO。随着时间的推移,POCO 的数量会增加,这会变得相当笨重。
建议的解决方案:我的团队建议我们将此过程与 MyPOCO 项目的 "build" 集成,但我不确定每个人都能掌握这个的可行性方法。所以,当我们'build' visual studio 中的项目时,上面的Main
方法实际上被执行了。以下是我发现这种方法存在的两个问题:
- 我如何 发现要序列化的 classes?目前我通过
AddPocoModel
方法将它们添加到主要方法中。但是,如果我不这样做,我如何通过反射发现它们并查询它们?
- 我如何 触发上面的主要方法post-build(即,它可以是一个自定义 class。我只是为了争论而使用
Main
。基本上,我如何触发 the 方法来完成 main 方法的功能以上)?
我该如何实现?或者,上面的问题有更好的解决办法吗?
我会把你的序列化器分解成一个单独的项目,一个控制台应用程序就可以了。此应用程序应采用指向刚刚编译的 DLL 的参数,然后您可以创建一个运行此工具并传入 DLL 名称的 post-build 命令。从好的方面来说,这为其他项目创建了一个可重用的工具。有许多宏,但您的最终看起来像这样:
"c:\path\to\serialization\tool.exe" $(TargetPath)
至于发现类型,因为您的 POCO 模型 类 与其他 类 可能没有什么区别(如果 DLL 中还有其他 类),所以您将需要以某种方式标记它们。我会使用自定义属性:
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class SerializePOCOAttribute : Attribute { }
然后你可以使用发现方法来枚举 DLL 中的所有 类 并序列化它们,例如:
public class POCOSerializer
{
public static void Serialize(string dllFileName, GenerateBulkVmXML batchSerializer)
{
var assem = Assembly.LoadFrom(dllFileName);
var pocoObjects = assem.GetTypes().Where(t => t.GetCustomAttribute<SerializePOCOAttribute>() != null);
foreach (var poco in pocoObjects)
{
batchSerializer.AddPocoModel(poco, poco.Namespace);
}
batchSerializer.WriteXML();
}
}
场景:
- 我有一个 visual studio 项目(例如 MyPOCO)中的 .cs 文件列表,其中包含一堆 POCO(普通旧 C# 对象)
- 我必须 运行 一个自定义序列化工具(自制并且我可以访问源代码)将这些 POCO 转换为 XML 文件 - 该工具通过反射完成此操作。
目前,MyPOCOs 项目被标记为 Console App 并且具有如下所示的主要方法:
class Program
{
static void Main(string[] args)
{
//Initialize custom XML Serializer
GenerateBulkVmXML batchSerializer = new GenerateBulkVmXML();
//Add individual POCOs to Serializer
batchSerializer.AddPocoModel(typeof(MyPOCO1), "My.Custom.NameSpace");
batchSerializer.AddPocoModel(typeof(MyPOCO2), "My.Custom.NameSpace1");
batchSerializer.AddPocoModel(typeof(MyPOCO3), "My.Custom.NameSpace2");
//Generate custom XML
batchSerializer .WriteXML();
}
}
每次我们 "run" 上述控制台应用程序时,它都会触发 Main
方法,该方法通过反射查询 POCO classes 并输出 XML。
问题:对于每一个新添加到项目中的POCO,我们都在上面的Main
方法中添加一行调用batchSerializer.AddPocoModel(...)
方法,通过传递他们输入新创建的 POCO。随着时间的推移,POCO 的数量会增加,这会变得相当笨重。
建议的解决方案:我的团队建议我们将此过程与 MyPOCO 项目的 "build" 集成,但我不确定每个人都能掌握这个的可行性方法。所以,当我们'build' visual studio 中的项目时,上面的Main
方法实际上被执行了。以下是我发现这种方法存在的两个问题:
- 我如何 发现要序列化的 classes?目前我通过
AddPocoModel
方法将它们添加到主要方法中。但是,如果我不这样做,我如何通过反射发现它们并查询它们? - 我如何 触发上面的主要方法post-build(即,它可以是一个自定义 class。我只是为了争论而使用
Main
。基本上,我如何触发 the 方法来完成 main 方法的功能以上)?
我该如何实现?或者,上面的问题有更好的解决办法吗?
我会把你的序列化器分解成一个单独的项目,一个控制台应用程序就可以了。此应用程序应采用指向刚刚编译的 DLL 的参数,然后您可以创建一个运行此工具并传入 DLL 名称的 post-build 命令。从好的方面来说,这为其他项目创建了一个可重用的工具。有许多宏,但您的最终看起来像这样:
"c:\path\to\serialization\tool.exe" $(TargetPath)
至于发现类型,因为您的 POCO 模型 类 与其他 类 可能没有什么区别(如果 DLL 中还有其他 类),所以您将需要以某种方式标记它们。我会使用自定义属性:
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class SerializePOCOAttribute : Attribute { }
然后你可以使用发现方法来枚举 DLL 中的所有 类 并序列化它们,例如:
public class POCOSerializer
{
public static void Serialize(string dllFileName, GenerateBulkVmXML batchSerializer)
{
var assem = Assembly.LoadFrom(dllFileName);
var pocoObjects = assem.GetTypes().Where(t => t.GetCustomAttribute<SerializePOCOAttribute>() != null);
foreach (var poco in pocoObjects)
{
batchSerializer.AddPocoModel(poco, poco.Namespace);
}
batchSerializer.WriteXML();
}
}