我有一個Activator.CreateInstanc的小問題,讓我先展示一些代碼。未找到C#.NET構造函數,反射
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文件名稱和完整的類型名稱。 任何幫助將非常感激。
驗證界面如果您有類型和同樣'FullName',但不同的程序集的版本,您可能會收到一個錯誤。我以前通過使用動力學來克服版本控制的類似問題(但那只是爲了測試,我不會推薦它用於生產代碼)。 –
我通過更改string [] possiableCommands = Directory.GetFiles(path,「* .dll」)修復了此問題; to string [] possiableCommands = Directory.GetFiles(path,「* Command.dll」); 我認爲當我加載並檢查其他沒有實現IPosCommand的dll時,一定會有一些奇怪的依賴關係,哦,它仍然有點奇怪,但至少它的排序。 謝謝大家。 – Jamie