How to convert objects in reflection (Linq to XML)

Posted by user829174 on Stack Overflow See other posts from Stack Overflow or by user829174
Published on 2012-04-15T10:50:43Z Indexed on 2012/04/15 11:29 UTC
Read the original article Hit count: 190

Filed under:
|
|

I have the following code which is working fine, the code creates plugins in reflection via run time:

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Xml.Linq;
using System.Reflection;
using System.Text;

namespace WindowsFormsApplication1
{
    public abstract class Plugin
    {
        public string Type { get; set; }
        public string Message { get; set; }
    }

    public class FilePlugin : Plugin
    {
        public string Path { get; set; }
    }

    public class RegsitryPlugin : Plugin
    {
        public string Key { get; set; }
        public string Name { get; set; }
        public string Value { get; set; }
    }

    static class MyProgram
    {
        [STAThread]
        static void Main(string[] args)
        {
            string xmlstr =@"
                <Client>
                  <Plugin Type=""FilePlugin"">
                    <Message>i am a file plugin</Message>
                    <Path>c:\</Path>
                  </Plugin>
                  <Plugin Type=""RegsitryPlugin"">
                    <Message>i am a registry plugin</Message>
                    <Key>HKLM\Software\Microsoft</Key>
                    <Name>Version</Name>
                    <Value>3.5</Value>
                  </Plugin>
                </Client>
              ";

            Assembly asm = Assembly.GetExecutingAssembly();
            XDocument xDoc = XDocument.Load(new StringReader(xmlstr));
            Plugin[]  plugins = xDoc.Descendants("Plugin")
                .Select(plugin =>
                {
                    string typeName = plugin.Attribute("Type").Value;
                    var type = asm.GetTypes().Where(t => t.Name == typeName).First();
                    Plugin p = Activator.CreateInstance(type) as Plugin;
                    p.Type = typeName;
                    foreach (var prop in plugin.Descendants())
                    {
                       var pi = type.GetProperty(prop.Name.LocalName);
                       object newVal = Convert.ChangeType(prop.Value, pi.PropertyType);
                       pi.SetValue(p, newVal, null);    
                    }

                    return p;
                }).ToArray();

            //
            //"plugins" ready to use
            //
        }
    }
}

I am trying to modify the code and adding new class named DetailedPlugin so it will be able to read the following xml:

    string newXml = @"
        <Client>
          <Plugin Type=""FilePlugin"">
            <Message>i am a file plugin</Message>
            <Path>c:\</Path>
            <DetailedPlugin Type=""DetailedFilePlugin"">
               <Message>I am a detailed file plugin</Message>
            </DetailedPlugin>
          </Plugin>
          <Plugin Type=""RegsitryPlugin"">
            <Message>i am a registry plugin</Message>
            <Key>HKLM\Software\Microsoft</Key>
            <Name>Version</Name>
            <Value>3.5</Value>
            <DetailedPlugin Type=""DetailedRegsitryPlugin"">
               <Message>I am a detailed registry plugin</Message>
            </DetailedPlugin>
          </Plugin>
        </Client>
      ";

for this i modified my classes to the following:

public abstract class Plugin
{
    public string Type { get; set; }
    public string Message { get; set; }
    public DetailedPlugin DetailedPlugin { get; set; } // new
}

public class FilePlugin : Plugin
{
    public string Path { get; set; }
}

public class RegsitryPlugin : Plugin
{
    public string Key { get; set; }
    public string Name { get; set; }
    public string Value { get; set; }
}

// new classes:
public abstract class DetailedPlugin
{
    public string Type { get; set; }
    public string Message { get; set; }
}

public class DetailedFilePlugin : Plugin
{
    public string ExtraField1 { get; set; }
}

public class DetailedRegsitryPlugin : Plugin
{
    public string ExtraField2{ get; set; }
}

from here i need some help to accomplish reading the xml and create the plugins with the nested DetailedPlugin

© Stack Overflow or respective owner

Related posts about c#

Related posts about LINQ