Опитвам се да стартирам малък механизъм за приставка, като отразявам dll файл, предоставящ моя клас Plugin
(имплементирайки моя Plugin
-интерфейс, споделен между dll и основния проект / съжалявам, че назовавам и двата еднакви), предлагайки атрибут от тип string
и main- метод activate
:
Интерфейс:
public interface Plugin
{
string pluginName{get;set;}
void activate(System.Windows.Forms.Form main);
}
dll клас:
public class Plugin : WhiteA.Plugin
{
public string pluginName{get;set;}
public void activate(System.Windows.Forms.Form main){
//find the right form to modify it
IEnumerable<System.Windows.Forms.ComboBox> ie= GetControlsOfType<System.Windows.Forms.ComboBox>(main);
System.Windows.Forms.ComboBox cb=GetControlsOfType<System.Windows.Forms.ComboBox>(main).FirstOrDefault();
cb.Items.Add("Modification");
System.Windows.Forms.MessageBox.Show(cb.SelectedItem.ToString());
}
public static IEnumerable<T> GetControlsOfType<T>(System.Windows.Forms.Control root)
where T : System.Windows.Forms.Control
{
var t = root as T;
if (t != null)
yield return t;
var container = root as System.Windows.Forms.ContainerControl;
if (container != null)
foreach (System.Windows.Forms.Control c in container.Controls)
foreach (var i in GetControlsOfType<T>(c))
yield return i;
}
}
Така че тук идва проблемът, няма type
с име "Plugin"
, който да бъде намерен в сборката. Опитах се да получа всички типове от всички сборки в директорията, да получа всички методи/членове/персонализирани атрибути от тях, да ги регистрирам и т.н., но няма нищо от моя клас Plugin
, което да бъде намерено, докато dll определено се намира, тъй като не връща MessageBox
.
string[] files=new string[]{};
string path="Error retrieving path";
try{
path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
files = System.IO.Directory.GetFiles(path, "*.dll");
}catch(Exception exF){
}
if(files.Length>0){
foreach (string dll in files){
try{
System.Reflection.Assembly sampleAssembly = System.Reflection.Assembly.LoadFrom(dll);
Type myType = sampleAssembly.GetType("Plugin");
System.Reflection.MethodInfo method = myType.GetMethod("activate");
object myInstance = Activator.CreateInstance(myType);
method.Invoke(myInstance, new object[]{this});
}catch(Exception exL){
}
}
}else{
MessageBox.Show("No working plugins detected in " + path.ToString(), "Nothing to activate", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
}
Знам, че моят код вероятно изглежда наистина объркан за всички вас - мисля, че последният try
-блок е единственото уместно нещо тук, но исках да сложа самия клас и интерфейса за малко прозрачност - и моят английски не е перфектен , но се надявам, че някой може да ми помогне да намеря моя атрибут+метод в сборката.
РЕДАКТИРАНЕ:
try{
System.Reflection.Assembly sampleAssembly = System.Reflection.Assembly.LoadFrom(dll);
List<Type> list= sampleAssembly.GetTypes().Where(p =>
p.Namespace == dll &&
p.Name.Contains("Plugin")
).ToList();
Type myType=list.FirstOrDefault();
//Type myType = sampleAssembly.GetType("Plugin");
System.Reflection.MethodInfo method = myType.GetMethod("activate");
object myInstance = Activator.CreateInstance(myType);
method.Invoke(myInstance, new object[]{this});
}
Промених го според Получаване на всички типове в пространство от имена чрез отражение Все още същият резултат, какво направих погрешно?
GetType()
? като напримерsampleAssembly.GetType("MyApp.Plugins.Plugin");
? Обърнете внимание, че не трябва да предавате името на сборката - вижте документите - person stuartd   schedule 01.06.2017