没有找到c# . net构造函数,反射

本文关键字:构造函数 反射 net | 更新日期: 2023-09-27 18:06:42

我在使用Activator时遇到了一个小问题。创建实例,让我从一些代码开始。

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

使用上面的代码,我得到一个missingmethodexception,说它找不到构造函数。现在奇怪的是,如果我使用这段代码,它工作得很好。

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文件名和完整的类型名称。

没有找到c# . net构造函数,反射

在第一个加载器中,不要使用IsTypePosCommand的实现,尝试使用return type.IsAssignableFrom(typeof(IPosCommand))。它可能无法正确判断类型

汇编中可能有继承IPosCommand的类,但没有带有一个applicationRepository类型参数的构造函数。尝试用typeof(WinformRenderer).GetConstructor(Type[] types)更精确地过滤出类。还可以用typeof(WinformRenderer).GetInterface(name, true)

验证您的接口。