Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Activator.CreateInstance can't find the constructor (MissingMethodException)

I have a class which has the following constructor

public DelayCompositeDesigner(DelayComposite CompositeObject)
{
    InitializeComponent();

    compositeObject = CompositeObject;  
}

along with a default constructor with no parameters.

Next I'm trying to create an instance, but it only works without parameters:

var designer = Activator.CreateInstance(designerAttribute.Designer);

This works just fine, but if I want to pass parameters it does not:

var designer = Activator.CreateInstance(designerAttribute.Designer, new DelayComposite(4));

This results in an MissingMethodException:

Constructor voor type Vialis.LightLink.Controller.Scenarios.Composites.DelayCompositeDesigner was not found

Any ideas here?


The problem is I really need to pass an object during construction.

You see I have a designer which loads all the types that inherit from the CompositeBase. These are then added to a list from which the users can drag them to a designer. Upon doing so an instance of the dragged is added to the designer. Each of these classes have custom properties defined on them:

[CompositeMetaData("Delay","Sets the delay between commands",1)]
[CompositeDesigner(typeof(DelayCompositeDesigner))]
public class DelayComposite : CompositeBase
{
}

When the user selects an item in the designer, it looks at these attributes in order to load up a designer for that type. For example, in the case of the DelayComposite it would load up a user control which has a label and a slider which allow the user to set the "Delay" property of the DelayComposite instance.

So far this works fine if I don't pass any parameters to the constructor. The designer creates an instance of the DelayCompositeDesigner and assigns it to the content property of a WPF ContentPresenter.

But since that designer needs to modify the properties of the selected DelayComposite in the designer, I have to pass this instance to it. That is why the constructor looks lie this:

public DelayCompositeDesigner(DelayComposite CompositeObject)
{
    InitializeComponent();

    compositeObject = CompositeObject;
}

Suggestions are welcome


@VolkerK

The result of your code is this:

<---- foo Vialis.LightLink.Controller.Scenarios.Composites.DelayCompositeDesignerVoid .ctor() Vialis.LightLink.Controller.Scenarios.Composites.DelayCompositeDesignerVoid .ctor(Vialis.LightLink.Controller.Scenarios.Composites.DelayComposite) param:Vialis.LightLink.Controller.Scenarios.Composites.DelayComposite foo ---->


Leppie, you were correct, I had for some reason referenced the Composites assembly in my UI application... which is not something I should have done as I was loading it at runtime. The following code works:

object composite = Activator.CreateInstance(item.CompositType,(byte)205);
                    var designer = Activator.CreateInstance(designerAttribute.Designer, composite);

As you can see the code does not have knowledge of the DelayComposite type.

This solves the current problem, but introduces many new ones for what I want to achieve, either way thank you and thank you to everyone who has replied here.


As for the following code, suggested by multiple people:

var designer = Activator.CreateInstance(
    designerAttribute.Designer, 
    new object[] { new DelayComposite(4) } 
);

The Activator.CreateInstance has a signature that looks like this:

Activator.CreateInstance(Type type, params object[] obj)

So it should accept my code, but I will try the suggested code

UPDATE:

I've tried this as suggested:

var designer = Activator.CreateInstance(designerAttribute.Designer, new object[] { new DelayComposite(4)});

The result is the same.

like image 789
TimothyP Avatar asked Oct 16 '08 14:10

TimothyP


4 Answers

I would think that your call would need to be:

var designer = Activator.CreateInstance(designerAttribute.Designer, new object[] { new DelayComposite(4) });

Unless, of course, it is that, in which case the answer is not immediately obvious.

like image 124
DocMax Avatar answered Sep 28 '22 06:09

DocMax


I think you are dealing with a Type mismatch.

Likely the assembly is referenced in different places, or they are compiled against different versions.

I suggest you iterate through the ConstructorInfo's and do a paramtype == typeof(DelayComposite) on the appropriate parameter.

like image 45
leppie Avatar answered Sep 28 '22 05:09

leppie


Though I hate printf-like debugging ...

public static void foo(Type t, params object[] p)
{
    System.Diagnostics.Debug.WriteLine("<---- foo");
    foreach(System.Reflection.ConstructorInfo ci in t.GetConstructors())
    {
        System.Diagnostics.Debug.WriteLine(t.FullName + ci.ToString());
    }
    foreach (object o in p)
    {
        System.Diagnostics.Debug.WriteLine("param:" + o.GetType().FullName);
    }
    System.Diagnostics.Debug.WriteLine("foo ---->");
}
// ...
foo(designerAttribute.Designer, new DelayComposite(4));
var designer = Activator.CreateInstance(designerAttribute.Designer, new DelayComposite(4));

What does that print in the visual studio's output window?

like image 7
VolkerK Avatar answered Sep 28 '22 05:09

VolkerK


If you want to call this contructor...

public DelayCompositeDesigner(DelayComposite CompositeObject)

...just use this:

var designer = Activator.CreateInstance(typeof(DelayCompositeDesigner), new DelayComposite(4));

or

var designer = Activator.CreateInstance<DelayCompositeDesigner>(new DelayComposite(4));
like image 3
Ishmaeel Avatar answered Sep 28 '22 07:09

Ishmaeel