Вземете методи и атрибути от dll сборка

Опитвам се да стартирам малък механизъм за приставка, като отразявам 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});

                    }

Промених го според Получаване на всички типове в пространство от имена чрез отражение Все още същият резултат, какво направих погрешно?


person Community    schedule 01.06.2017    source източник
comment
Мисля, че трябва да предадете пространството от имена на GetType()? като например sampleAssembly.GetType("MyApp.Plugins.Plugin");? Обърнете внимание, че не трябва да предавате името на сборката - вижте документите   -  person stuartd    schedule 01.06.2017
comment
Тук е отговорено. stackoverflow.com/questions/79693/   -  person JWP    schedule 01.06.2017
comment
@stuartd това би означавало, че всичките ми добавки трябва да имат едно и също пространство от имена, нали? Това необходимо/позволено ли е?   -  person    schedule 01.06.2017
comment
Докато всички са в различни сборки, тогава е ОК.   -  person stuartd    schedule 01.06.2017


Отговори (1)


Както е посочено от @stuartd:

Type myType = sampleAssembly.GetType("WhiteA_Plugin_PausedVideo.Plugin");

е решението, пропусна пространството от имена

cb.Items.Add("Modification");

не работи обаче ... някакви предложения?

Работи получавайки деца на формуляра чрез Controls["nameOfChild"] директно, този помощен метод за извличане на всички обекти по клас изглежда е грешен тук.

Приставката вече работи, благодаря!

person Community    schedule 05.07.2017