How to use XmlSerializer with classes produced from CompileAssemblyFromSource ?

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
I dynamicaly generate code and use the <font color="#008080" size=2>CodeDomProvider </font>and  <font size=2>CompileAssemblyFromSource </font>to produce an in memory Assembly. The generated code uses List<T> as one of the Properties.
I then need to stream XML into and out of a class in the in memory Assembly. 
I first use the  <font color="#008080" size=2>Activator </font>   to create an instance of the class: <font size=2>
</font><font face="Courier New, Courier, Monospace" color="#008080" size=2>Assembly</font><font size=2><font face="Courier New, Courier, Monospace assembly = results.CompiledAssembly;</font>
</font><font face="Courier New, Courier, Monospace" color="#008080" size=2>Type</font><font size=2><font face="Courier New, Courier, Monospace [] exportedTypes = assembly.GetExportedTypes();</font>
<font face="Courier New, Courier, Monospace object rc = </font></font><font face="Courier New, Courier, Monospace <font color="#008080" size=2>Activator</font><font size=2>.CreateInstance(exportedTypes[0])</font></font>
The next step is to put the object in a Property Grid and fill it with data.
So far so good.
The problem occurs when i try to use the <font color="#008080" size=2>XmlSerializer</font> to write it out as XML:
<font face="Courier New, Courier, Monospace             StringWriter sw1 = new StringWriter();
            Type type = rc.GetType();
            XmlSerializer xs = new XmlSerializer(type, "Common.Generated");
            try
            {
                using (XmlTextWriter writer = new XmlTextWriter(sw1))
                {
                    writer.Formatting = Formatting.Indented;
                    xs.Serialize(writer, rc);
                }
                Log(sw1.ToString());
               
            }
            catch (Exception ex)
            {
                Log(ex.ToString());
            }</font>
<font face=Arial>I get the following exception:</font>
<font face="Courier New, Courier, Monospace System.InvalidOperationException: There was an error generating the XML document. ---> System.TypeInitializationException: The type initializer for Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterXXX threw an exception. ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterXXX..cctor()
   --- End of inner exception stack trace ---
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterXXX..ctor()
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializerContract.get_Writer()
   at System.Xml.Serialization.TempAssembly.InvokeWriter(XmlMapping mapping, XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   --- End of inner exception stack trace ---
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle, String id)
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o)
</font>
<font face="Courier New, Courier, Monospace <font face=Arial>If I cut and past the generated code into a simple Test Program it compiles and Serializes fine, using the same code from above.</font></font>
<font face="Courier New, Courier, Monospace <font face=Arial>Here is a sample of the Generated Code:</font> </font>
<font face="Courier New, Courier, Monospace" size=2>namespace Common.Generated
{
    [Serializable()]
    [XmlRoot("CONFIGURATION")]
    public class XXX
    {
        [XmlInclude(typeof(XXX.ITEM))]
        [XmlInclude(typeof(List<XXX.ITEM>))]
        [Serializable()]
        public class ITEM
        {
            public ITEM() { }</font>
<font face="Courier New, Courier, Monospace" size=2>            private string NameField = String.Empty;
            [XmlElement("NAME")]
            public string Name
            {
                get { return (this.NameField); }
                set { this.NameField = value; }
            }
        }</font>
<font face="Courier New, Courier, Monospace" size=2>        public XXX() { }</font>
<font face="Courier New, Courier, Monospace" size=2>        private List<XXX.ITEM> items_ = new List<XXX.ITEM>();
        [XmlArray("ITEMS")]
        [XmlArrayItem("ITEM", Type=typeof(XXX.ITEM))]
        public List<XXX.ITEM> Items
        {
            get { return ( this.items_ ); }
            set { this.items_ = value; }
        }
    }
}
</font>
<font face="Courier New, Courier, Monospace" size=2><font face=Arial size=3>Here is a sample of how I am compiling the code:</font></font>
<font size=2><font face="Courier New, Courier, Monospace" size=3>                CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
                CompilerParameters compilerParameters = new CompilerParameters();</font></font>
<font size=2><font face="Courier New, Courier, Monospace" size=3>                compilerParameters.ReferencedAssemblies.Add("System.dll");
                compilerParameters.ReferencedAssemblies.Add("mscorlib.dll");
                compilerParameters.ReferencedAssemblies.Add("system.xml.dll");
                compilerParameters.ReferencedAssemblies.Add("system.data.dll");
                compilerParameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
                compilerParameters.IncludeDebugInformation = false;
                compilerParameters.GenerateExecutable = false;
                compilerParameters.GenerateInMemory = true;</font></font>
<font size=2><font face="Courier New, Courier, Monospace" size=3>                CompilerResults results = provider.CompileAssemblyFromSource(compilerParameters, _code);</font></font>
<font size=2><font face="Courier New, Courier, Monospace" size=3>                if (results.Errors.HasErrors)
                {
                    Log("Error compiling assembly:");
                    foreach (CompilerError error in results.Errors)
                    {
                        Log(error.ErrorText);
                    }
                }
                else
                {
                    Assembly assembly = results.CompiledAssembly;
                    Type[] exportedTypes = assembly.GetExportedTypes();
                    rc = Activator.CreateInstance(exportedTypes[0]);
                    Log("OK");
                }
            }</font></font>
<font face="Courier New, Courier, Monospace" size=2><font face=Arial size=3>Any help would be apprecieated...</font></font>
 
 
<font face="Courier New, Courier, Monospace" size=2><font face=Arial size=3></font>  </font>
 
 
 

View the full article
 
Back
Top