C# .NET Constructor not found , reflection
I have a small issue with Activator.CreateInstanc, let me start by showing some code.
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));
}
Above is the loader code, next is the code that implements 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";
}
}
}
Using the above code I get a missingmethodexception , saying it cant find the constructor. Now the strange part is , if I use this code it works fine.
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;
}
The two versions of the loader works a little different , the first scans the directory for all .dll files and then checks to see if the type implements the IPosCommand, the second loader code , knows the dll file name and full type name already. Any help would be very much appreciated.
In the first loader, instead of using your implemenatation of IsTypePosCommand
try to use return type.IsAssignableFrom(typeof(IPosCommand))
. It probably can't correctly determine the type.
There may be classes in assembly inheriting IPosCommand
but no constructor with one argument of type applicationRepository. Try filtering out the class more precisely with typeof(WinformRenderer).GetConstructor(Type[] types)
Also verify your interface with typeof(WinformRenderer).GetInterface(name, true)
精彩评论