Конструктор C # .NET не найден, отражение - PullRequest
0 голосов
/ 25 августа 2011

У меня небольшая проблема с Activator.CreateInstanc, позвольте мне начать с показа некоторого кода.

public class CommandLoader
{
    public List<IPosCommand> LoadCommands(string path, ApplicationRepository applicationRepository)
    {
        object[] args = new object[] {applicationRepository};

        List<IPosCommand> commands = new List<IPosCommand>();
        string[] possiableCommands = Directory.GetFiles(path, "*.dll");

        foreach (string file in possiableCommands)
        {
            IPosCommand command = GetCommand(file, args);
            if(command != null)
                commands.Add(command);
        }
        return commands;
    }
    private IPosCommand GetCommand(string file,object[] args)
    {
        try
        {
            Assembly assembly = Assembly.LoadFrom(file);
            foreach (Type type in assembly.GetTypes())
            {
                bool isPosCommand = IsTypePosCommand(type);

                if (isPosCommand)
                {

                                IPosCommand command = (IPosCommand)Activator.CreateInstance(type, args);
                                return command;

                }
              }

            }
        }
        catch (ReflectionTypeLoadException)
        {
        }
        return null;
    }

    private bool IsTypePosCommand(Type type)
    {
        return type.GetInterfaces().Any(x => x == typeof (IPosCommand));
    }

Выше приведен код загрузчика, затем код, реализующий IPosCommand.

 public class SignOffCommand : IPosCommand
{
    private ApplicationRepository applicationRepository;

    public SignOffCommand(ApplicationRepository applicationRepository)
    {
        this.applicationRepository = applicationRepository;
    }
    public CommandInfomation CommandInfomation { get; set; }
    public bool PlaceAtTopAndWaitForNextCommand { get; set; }
    public void Execute(object Sender, string commandText)
    {
        if (commandText == "SIGNOFF")
        {
            ISalesView view = applicationRepository.Get<ISalesView>();
            if (view != null)
            {
                IOperatorSessionManager sessionManager = applicationRepository.Get<IOperatorSessionManager>();
                if (sessionManager != null)
                {
                    sessionManager.OnOperatorSignOff(view.CurrentOperator);
                }

                view.CurrentOperator = null;

                throw new ForceStopException();
            }
        }
    }

    public string GetCommandText
    {
        get
        {
            return "SIGNOFF";
        }
    }
    public string CommandName
    {
        get
        {
            return "SIGNOFF";
        }
    }
}

Используя приведенный выше код, я получаю отсутствующее исключение метода, говоря, что не могу найти конструктор.Теперь странная часть: если я использую этот код, он работает нормально.

public enum CommandType{
    System,
    User
}

[Serializable]
public class CommandInfomation
{
    public string DllName { get; set; }
    public string FullName { get; set; }
    public CommandType CommandType { get; set; }
}

  public List<IPosCommand> LoadCommands(ApplicationRepository applicationRepository)
    {
        List<CommandInfomation> commandInfomations =
            AppDataSerializer.Load<List<CommandInfomation>>("CommandInfomation.xml");


        List<IPosCommand> commands = new List<IPosCommand>();
        foreach (CommandInfomation infomation in commandInfomations)
        {

            Assembly assembly = Assembly.LoadFrom(infomation.DllName);

            object[] args = new Object[] {applicationRepository};
            Type type = assembly.GetType(infomation.FullName, false);

            IPosCommand command = (IPosCommand) Activator.CreateInstance(type, args);

            command.CommandInfomation = infomation;

            commands.Add(command);

        }
        return commands;
    }

Две версии загрузчика работают немного по-разному, сначала сканирует каталог на наличие всех DLL-файлов, а затем проверяет, чтобы увидетьесли тип реализует IPosCommand, второй код загрузчика, уже знает имя файла dll и полное имя типа.Любая помощь будет принята с благодарностью.

Ответы [ 2 ]

1 голос
/ 25 августа 2011

Могут быть классы в сборке, наследующие IPosCommand, но нет конструктора с одним аргументом типа applicationRepository.Попробуйте отфильтровать класс более точно с помощью typeof(WinformRenderer).GetConstructor(Type[] types) Также проверьте свой интерфейс с помощью typeof(WinformRenderer).GetInterface(name, true)

1 голос
/ 25 августа 2011

В первом загрузчике вместо использования вашей реализации IsTypePosCommand попробуйте использовать return type.IsAssignableFrom(typeof(IPosCommand)).Возможно, он не может правильно определить тип.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...