Scenario:
Currently, MyPOCOs project is marked as a Console App and has a main method like the one below:
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();
}
}
Everytime we "run" the above console app, it triggers the Main
method, that queries the POCO classes via reflection and spews out the XML.
Problem: For every new POCO added to the project, we have add a line to the above Main
method calling the batchSerializer.AddPocoModel(...)
method by passing they type of the newly created POCO. Overtime, the number of POCOs will increase and this well get rather unwieldy.
Proposed Solution: My team suggests we integrate this process with the "build" of the MyPOCO project, but I'm not sure everyone can grasp the viability of this approach. So, when we 'build' the project in visual studio, the above Main
method gets executed, in essence. Here are the two problems I see with this approach:
AddPocoModel
method. But if I don't do that, how can I discover them and query them via reflection?Main
for the sake of argument. Basically, how can I trigger the method that does what the main method does above)?How do I achieve this? Or, is there a better solution to the above problem?
I would break out your serializer into a separate project, a console application would be just fine. This application should take an argument pointing to the DLL that was just compiled, you can then create a post-build command that runs this tool and passes in the DLL name. On the plus side, this creates a reusable tool for other projects. There are a number of macros, but yours would end up looking something like:
"c:\path\to\serialization\tool.exe" $(TargetPath)
As for discovering the types, since there is probably nothing differentiating your POCO model classes from other classes (if there are other classes in the DLL), so you will need to mark them somehow. I'd go with a custom attribute:
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class SerializePOCOAttribute : Attribute { }
Then you can use a discovery method for enumerating all the classes in the DLL and serializing them, something like:
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();
}
}