Активатор.CreateInstance не может найти конструктор (MissingMethodException)

у меня есть класс, который имеет следующий конструктор

public DelayCompositeDesigner(DelayComposite CompositeObject)
{
    InitializeComponent();

    compositeObject = CompositeObject;  
}

вместе с конструктор по умолчанию без параметров.

далее я пытаюсь создать экземпляр, но он работает только без параметров:

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

это работает просто отлично, но если я хочу передать параметры, это не так:

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

в результате MissingMethodException:

конструктор типа voor Vialis.LightLink.Контроллер.Вариант развития событий.Композиты.DelayCompositeDesigner не было найдено

есть идеи?


проблема в том, что мне действительно нужно передать объект во время строительства.

вы видите, что у меня есть дизайнер, который загружает все типы, которые наследуются от CompositeBase. Затем они добавляются в список, из которого пользователи могут перетаскивать их в конструктор. При этом экземпляр перетаскиваемого добавляется в конструктор. Каждый из них классы имеют свойства, определенные на них:

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

когда пользователь выбирает элемент в конструкторе, он смотрит на эти атрибуты для того, чтобы загрузить конструктор для этого типа. Например, в случае DelayComposite он загрузит пользовательский элемент управления, который имеет метку и ползунок, которые позволяют пользователю установить свойство "Delay"DelayComposite экземпляра.

пока это работает нормально, если я не передаю никаких параметров конструктору. Конструктор создает пример DelayCompositeDesigner и присваивает его свойству содержимого WPF ContentPresenter.

но так как этот дизайнер должен изменить свойства выбранного DelayComposite в конструкторе я должен передать ему этот экземпляр. Вот почему конструктор выглядит так:

public DelayCompositeDesigner(DelayComposite CompositeObject)
{
    InitializeComponent();

    compositeObject = CompositeObject;
}

предложения приветствуются


@VolkerK

результат вашего кода таков:


Леппи, вы были правы, я почему-то ссылался на сборку Composites в моем приложении UI... чего не надо сделали, как я загружал его во время выполнения. Работает следующий код:

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

как вы можете видеть код, не имеющий знания о DelayComposite тип.

это решает текущую проблему, но вводит много новых, для чего я хочу добиться, в любом случае спасибо и спасибо всем, кто ответил Здесь.


что касается следующего кода, предложенного несколькими людьми:

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

на Activator.CreateInstance имеет подпись, которая выглядит так:

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

поэтому он должен принять мой код, но я попробую предложенный код

обновление:

я пробовал это, как было предложено:

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

результат тот же.

9 ответов


Я думаю, вы имеете дело с несоответствием типов.

вероятно, на сборку ссылаются в разных местах или они компилируются с разными версиями.

Я предлагаю вам выполнить итерацию через ConstructorInfo и сделать paramtype == typeof(DelayComposite) по соответствующему параметру.


Я бы подумал, что ваш звонок должен быть:

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

если, конечно, это is, что в этом случае ответ не сразу очевиден.


хотя я ненавижу 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));

что это печатает в окне вывода visual studio?


Если вы хотите назвать это contructor...

public DelayCompositeDesigner(DelayComposite CompositeObject)

...просто используйте это:

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

или

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

У меня была аналогичная проблема, однако моя проблема была связана с видимостью конструктора. Это переполнение стека помогло мне:

создание экземпляра конструктора с параметрами во внутреннем классе с отражением


Я обнаружил другой способ создания экземпляра объекта без вызова конструктора вообще в то время как ответ еще один вопрос о SF.

на


вы можете использовать следующую перегрузку на CreateInstance:

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

и в вашем случае это было бы (я думаю):

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

Я нашел решение проблемы, я боролся с той же проблемой.

вот мой активатор:

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

и вот мой класс для активации, обратите внимание, что мне пришлось изменить параметры конструктора объекты, только так я мог заставить его работать.

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

когда я столкнулся с этой проблемой, я использовал метод, который вернул список параметров для подключения к Activator.CreateInstance и у него было другое количество аргументов, чем у конструктора объекта, который я пытался создать.