Search code examples
c#.netdll.net-assemblycodedom

Compile class with attributes and load


Not sure why this doesn't work, basically this is my code:

System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = false;
parameters.OutputAssembly = @"C:\myclass.dll";
string code = @"
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;

namespace First
{
    public class B
    {
        public List<string> list = new List<string>();

        [DisplayName(""Pos""),Category(""Test""),DefaultValue(0),DefaultValueAttribute(0)]
        public int Position { get; set; }
    }
}
";
CompilerResults r = CodeDomProvider.CreateProvider("CSharp").CompileAssemblyFromSource(parameters, code);
var DLL = Assembly.LoadFile(parameters.OutputAssembly);
foreach (Type type in DLL.GetExportedTypes())
{
    dynamic c = Activator.CreateInstance(type);
    _props.SelectedObject = c;
}

Loading the class into a property grid works fine but the attributes are ignored, any ideas why? and is there a solution for this?


Solution

  • First of all you code doesn't even compiles for me. It needs some of the changes.

    • You need to reference System.dll
    • There is duplicate DefaultValue attribute in your code, you need to remove it

    It is hard to believe you get the assembly compiled with this code. I've updated the code and it works as expected.

    System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
    parameters.GenerateExecutable = false;            
    parameters.OutputAssembly = @"C:\myclass.dll";
    parameters.ReferencedAssemblies.Add("System.dll");//Add reference
    
    string code = @"
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    
    namespace First
    {
        public class B
        {
            public List<string> list = new List<string>();
    
            [DisplayName(""Pos""),Category(""Test""),DefaultValue(0)]
            public int Position { get; set; }
        }
    }
    ";
    
    CompilerResults r = CodeDomProvider.CreateProvider("CSharp").CompileAssemblyFromSource(parameters, code);
    if (r.Errors.Count <= 0)
    {
        var DLL = Assembly.LoadFile(parameters.OutputAssembly);
        foreach (Type type in DLL.GetExportedTypes())
        {
            dynamic c = Activator.CreateInstance(type);
            _props.SelectedObject = c;
        }
    }