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.
Though I hate printf-like debugging ...
What does that print in the visual studio's output window?
I found a solution to the problem, I was struggling with the same issue.
Here is my activator:
And here is my class to activate, note that I had to change the constructor params to objects, the only way I could get it to work.
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.I discovered another way of creating an instance of an object without calling the constructor at all while answering another question on SF.
In the System.Runtime.Serialization namespace there is a function FormatterServices.GetUninitializedObject(type) that will create an object without calling constructor.
If you look at that function in Reflector you will see it is making an external call. I don't know how black magic is actually happening under the hood. But I did prove to myself that the constructor was never called but the object was instantiated.
When I encountered this problem, I was using a method that returned the parameter list to plug in to Activator.CreateInstance and it had a different number of arguments than the constructor of the object I was trying to create.
I had a similar issue, however my problem was due to the visibility of the constructor. This stack overflow helped me:
Instantiating a constructor with parameters in an internal class with reflection