locked
Reflection - Creating class at runtime throwing error RRS feed

  • Question

  • User-1343058805 posted

    Hi All,

    I have a abstract class and bunch of concrete classes implementing the abstract class. This scenario is working fine in normal class creation but requirement has changed. As per new requirement concrete class should be generated at runtime, I am using following code:

    namespace NSUser.Entity
    {
    public abstract class testApprover
    {

          protected testApprover nextLevel;
          public int UserID { get; set; }
         public string UserName { get; set; }

        public testApprover()
        { }

       public void SetNextLevel(testApprover nLevel)
       {
          this.nextLevel= nLevel;
        }

       public virtual string ProcessQuery(Job job, enumAction action)
       {
            ......
        }
    }

    public AssemblyBuilder CreateObject()
    {
       AssemblyName assemblyName = new AssemblyName();
       assemblyName.Name = "DynamicReflect";
       AppDomain thisDomain = AppDomain.CurrentDomain;
       asmBuilder = thisDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
       modBuilder = asmBuilder.DefineDynamicModule(asmBuilder.GetName().Name, "DynamicLib.dll");

       TypeBuilder typeBuilder = null;
       DataSet ds = createTable();
       Type generetedType = null;
       string cName = null;
       foreach (DataRow dr in ds.Tables[0].Rows) //class names are coming from database
       {
          cName = dr["WFClassName"].ToString();
          var classType = new CodeTypeDeclaration(dr[0].ToString());
         classType.Attributes = MemberAttributes.Public;
         classType.BaseTypes.Add("NSUser.Entity.testApprover");

         typeBuilder = modBuilder.DefineType(dr[0].ToString(),
         TypeAttributes.Public |
         TypeAttributes.Class |
         TypeAttributes.AutoClass |
        TypeAttributes.AnsiClass |
        TypeAttributes.BeforeFieldInit |
        TypeAttributes.AutoLayout,
        typeof(NSUser.Entity.testApprover),null);

        Type[] ctorParams = new Type[] {};
        generetedType = typeBuilder.CreateType();

      }

      foreach (DataRow dr in ds.Tables[0].Rows)
     {
         Type _typeName = asmBuilder.GetType(dr["WFClassName"].ToString());
         object ptInstance = Activator.CreateInstance(_typeName);
        ((testApprover)ptInstance).UserName = "test";

        PropertyInfo prop = _typeName.GetProperty("UserName");
       prop.SetValue(((testApprover)ptInstance).UserName, "test");
    THROWING FOLLOWING ERROR:
    An unhandled exception of type 'System.Reflection.TargetException' occurred in mscorlib.dll
    Additional information: Object does not match target type.
    }
    return asmBuilder;
    }

    Goal is to create a following concrete class 

    namespace NSUser.Entity
    {
    class Initiator : testApprover
    {

    }
    }

    testApprover _initiator = new Initiator() { UserName = "testuser" };

    Please let me know how to resolve/achieve this using reflection.

    Thanks

    Sham

    Friday, October 16, 2015 7:53 AM

Answers

  • User-1343058805 posted

    Hi All,

    Thanks a lot for all your help, I am stuck at final step. How to invoke SetNextLevel method from created instance on above code.

    Type _typeName = asmBuilder.GetType(dr["WFClassName"].ToString());
    object ptInstance = Activator.CreateInstance(_typeName);

    -- nextLevel is protected, when I do following assignment returning ERROR

    ((testApprover)ptInstance ).SetNextLevel ="new class instance"
    Cannot assign to 'SetNextLevel' because it is a 'method group'   <-- ERROR

    Thanks
    Sham

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, November 2, 2015 9:40 AM

All replies

  • User-1343058805 posted

    After making some changes, receiving following error.

    Additional information: Non-static method requires a target.

    Please let me know how to resolve.

    Sunday, October 18, 2015 10:29 PM
  • User-219423983 posted

    Hi sham,

    About the error “Object does not match target type”, you should just replace

    prop.SetValue(((testApprover)ptInstance).UserName, "test");

    with

    prop.SetValue(((testApprover)ptInstance), "test");

    in your code. According to the following link, the first parameter represents an object whose property value will be set. So, here it should be an instance of a class.

    https://msdn.microsoft.com/en-us/library/hh194291(v=vs.110).aspx

    In your latest reply, you got error “Non-static method requires a target“, could you show which line happens the error and what did you change?

    I hope it’s useful to you.

    Best Regard,

    Weibo Zhang

    Monday, October 19, 2015 10:36 PM
  • User-1343058805 posted

    Hi Zhang,

    Thanks for your input, it worked I am able to assign the properties for each object coming from the database.

    Currently I have configuration to create 3 classes dynamically (above code) and returning created assembly to the caller.

    RuntimeObject runObj = new RuntimeObject();
    AssemblyBuilder runObject = runObj.CreateObject();   <--- returning above created assembly --->

    I do see all classes created previously in runObject, when I try to access one of the class property getting following error:

    ((testApprover)runObject.GetTypes()[0]).UserName
    Cannot convert type 'System.Type' to 'NSUser.Entity.testApprover'

    Thanks

    Sham

    Tuesday, October 20, 2015 4:46 PM
  • User-1343058805 posted

    Storing instance of each class in a list resolve the issue.

    Thanks for the help. Greatly appreciate for the time spent to answer my question.

    Tuesday, October 20, 2015 10:33 PM
  • User-1343058805 posted

    Hi All,

    Thanks a lot for all your help, I am stuck at final step. How to invoke SetNextLevel method from created instance on above code.

    Type _typeName = asmBuilder.GetType(dr["WFClassName"].ToString());
    object ptInstance = Activator.CreateInstance(_typeName);

    -- nextLevel is protected, when I do following assignment returning ERROR

    ((testApprover)ptInstance ).SetNextLevel ="new class instance"
    Cannot assign to 'SetNextLevel' because it is a 'method group'   <-- ERROR

    Thanks
    Sham

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, November 2, 2015 9:40 AM