type new how from example c# .net activator missingmethodexception

c# - new - Activator.CreateInstance no puede encontrar el constructor(MissingMethodException)



new gettype c# (8)

Encontré una solución al problema, estaba luchando con el mismo problema.

Aquí está mi activador:

private void LoadTask(FileInfo dll) { Assembly assembly = Assembly.LoadFrom(dll.FullName); foreach (Type type in assembly.GetTypes()) { var hasInterface = type.GetInterface("ITask") != null; if (type.IsClass && hasInterface) { var instance = Activator.CreateInstance(type, _proxy, _context); _tasks.Add(type.Name, (ITask)instance); } } }

Y aquí está mi clase para activar, nótese que tuve que cambiar los parámetros del constructor por objetos, la única forma en que podía hacer que funcionara.

public class CalculateDowntimeTask : Task<CalculateDowntimeTask> { public CalculateDowntimeTask(object proxy, object context) : base((TaskServiceClient)proxy, (TaskDataDataContext)context) { } public override void Execute() { LogMessage(new TaskMessage() { Message = "Testing" }); BroadcastMessage(new TaskMessage() { Message = "Testing" }); } }

Tengo una clase que tiene el siguiente constructor

public DelayCompositeDesigner(DelayComposite CompositeObject) { InitializeComponent(); compositeObject = CompositeObject; }

junto con un constructor predeterminado sin parámetros.

A continuación, intento crear una instancia, pero solo funciona sin parámetros:

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

Esto funciona bien, pero si quiero pasar parámetros, no:

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

Esto da como resultado una MissingMethodException :

No se encontró el constructor voor tipo Vialis.LightLink.Controller.Scenarios.Composites.DelayCompositeDesigner

Alguna idea aqui?

El problema es que realmente necesito pasar un objeto durante la construcción.

Usted ve que tengo un diseñador que carga todos los tipos que heredan de CompositeBase . Estos se agregan a una lista desde la cual los usuarios pueden arrastrarlos a un diseñador. Al hacerlo, se agrega una instancia del arrastre al diseñador. Cada una de estas clases tiene propiedades personalizadas definidas en ellas:

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

Cuando el usuario selecciona un elemento en el diseñador, mira estos atributos para cargar un diseñador para ese tipo. Por ejemplo, en el caso de DelayComposite cargaría un control de usuario que tiene una etiqueta y un control deslizante que permiten al usuario establecer la propiedad "Delay" de la instancia de DelayComposite .

Hasta ahora, esto funciona bien si no paso ningún parámetro al constructor. El diseñador crea una instancia de DelayCompositeDesigner y la asigna a la propiedad de contenido de WPF ContentPresenter .

Pero dado que ese diseñador necesita modificar las propiedades del DelayComposite seleccionado en el diseñador, tengo que pasarle esta instancia. Es por eso que el constructor parece mentir esto:

public DelayCompositeDesigner(DelayComposite CompositeObject) { InitializeComponent(); compositeObject = CompositeObject; }

Sugerencias son bienvenidas

@VolkerK

El resultado de tu código es este:

<---- 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, estabas en lo cierto, por alguna razón había hecho referencia al ensamblaje de Composites en mi aplicación de interfaz de usuario ... que no es algo que debería haber hecho ya que lo estaba cargando en tiempo de ejecución. El siguiente código funciona:

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

Como puede ver, el código no tiene conocimiento del tipo DelayComposite .

Esto resuelve el problema actual, pero presenta muchos nuevos para lo que quiero lograr, de cualquier manera, gracias y gracias a todos los que han respondido aquí.

En cuanto al siguiente código, sugerido por varias personas:

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

El Activator.CreateInstance tiene una firma que se ve así:

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

Por lo tanto, debería aceptar mi código, pero intentaré con el código sugerido

ACTUALIZAR:

He intentado esto como se sugiere:

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

El resultado es el mismo.


Creo que tu llamada debería ser:

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

A menos que, por supuesto, sea eso, en cuyo caso la respuesta no es inmediatamente obvia.


Puede usar la siguiente sobrecarga en CreateInstance:

public static Object CreateInstance( Type type, Object[] args )

Y en tu caso sería (creo):

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


Si quieres llamar a este contructor ...

public DelayCompositeDesigner(DelayComposite CompositeObject)

... solo usa esto:

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

o

var designer = Activator.CreateInstance<DelayCompositeDesigner>(new DelayComposite(4));


Aunque odio la depuración tipo printf ...

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));

¿Qué se imprime en la ventana de resultados del estudio visual?


Creo que estás lidiando con un tipo de desajuste.

Es probable que el ensamblaje esté referenciado en diferentes lugares, o se compilan contra versiones diferentes.

Te sugiero que iteres a través de ConstructorInfo y hagas un paramtype == typeof(DelayComposite) en el parámetro apropiado.


Descubrí otra forma de crear una instancia de un objeto sin llamar al constructor mientras respondía otra pregunta sobre SF.

En el espacio de nombres System.Runtime.Serialization hay una función FormatterServices.GetUninitializedObject (type) que creará un objeto sin llamar al constructor.

Si observa esa función en Reflector, verá que está realizando una llamada externa. No sé cómo la magia negra está sucediendo bajo el capó. Pero me demostré a mí mismo que el constructor nunca fue llamado, pero el objeto fue instanciado.