如何清除加载的程序集,以便在重新加载插件时,它不会重复?

时间:2016-07-06 15:59:08

标签: c# plugins listbox .net-assembly mef

我这样做是为了你可以打开一个dll并将它作为可点击的项目加载到列表框中,一旦点击,插件就会加载,你可以执行该插件。

I added a clear button that is suppose to clear the app of the currently loaded plugins.

It clears everything off the app but when I go to load them again, it loads duplicates.

如何清除程序集,以便在重新加载插件时,它不会重复?

代码背后:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using PluginContracts;
using System;
using System.IO;
using Microsoft.Win32;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System.Diagnostics;
using System.Linq;

namespace SimplePlugin
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>

    public partial class MainWindow : Window
    {

        Dictionary<string, IPlugin> _Plugins; // move to class scope


        public MainWindow()
        {
            InitializeComponent();
            _Plugins = new Dictionary<string, IPlugin>();

        }

        private void AssembleComponents(object sender)
        {


            string selection = "";
            if (sender is ListBox)
            {
                if (((ListBox)sender).SelectedValue != null)
                    selection = ((ListBox)sender).SelectedValue.ToString();
            }

            string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
            DirectoryCatalog cat = new DirectoryCatalog(path);

            //ICollection<IPlugin> plugins = PluginLoader.LoadPlugins("Plugins");
            ICollection<IPlugin> plugins = GenericPluginLoader<IPlugin>.LoadPlugins("Plugins");



            foreach (var item in plugins)
            {
                //add only if not already present
                if (!_Plugins.ContainsKey(item.Name))
                {
                    string dllName = GetDLLName(item.Name);

                    Button b = new Button() 
                    { 
                        Name = dllName.Replace(".", "").ToUpper(), 
                        Content = item.Name,
                        Visibility = System.Windows.Visibility.Hidden 
                    };

                    b.Click += b_Click;
                    PluginGrid.Children.Add(b);

                    _Plugins.Add(item.Name, item);



                   // this.PluginGrid.Children.Clear();  
                   //by Vasey

                }
            }


            // make visible the selected plugin button
   foreach (var ctl in PluginGrid.Children)
   {
       if (ctl is Button)
       {
           Button button = (Button)ctl;

           if (button.Name.Equals(selection.Replace(".", "").ToUpper()))
           {

               button.Visibility = System.Windows.Visibility.Visible;
           }
           else
           {
                button.Visibility = System.Windows.Visibility.Hidden;
           }
       }
   }
        }


        private void b_Click(object sender, RoutedEventArgs e)
        {
            Button b = sender as Button;
            if (b != null)
            {
                string key = b.Content.ToString();
                if (_Plugins.ContainsKey(key))
                {
                    IPlugin plugin = _Plugins[key];
                    plugin.Do();
                }
            }
        }

        private void addPlugin_Click(object sender, RoutedEventArgs e)
        {

            var fileDialog = new OpenFileDialog();

            fileDialog.Multiselect = true;
            fileDialog.Filter = "All files (*.*)|*.*|DLL files (*.dll)|*.dll|CS Files (*.cs)|*.cs";

            if (fileDialog.ShowDialog() == true)
            {
                string filename = fileDialog.FileName;
                var ext = System.IO.Path.GetExtension(filename);

                // ListBox lbFiles = new ListBox();

                //this.Controls.Add(lbFiles);
                //lbFiles.Size = new System.Drawing.Size(200, 100);
                //lbFiles.Location = new System.Drawing.Point(10, 10);

                lbFiles.Items.Add(System.IO.Path.GetFileName(filename));
                //  

                CopyToDir(filename);
            }
        }

        private void CopyToDir(string filename)
        {
            //  txtBox.Text = "Hello World";  
            string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
            Console.WriteLine(path);
            //Check the directory exists
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            try
            {
                FileInfo fi = new FileInfo(filename);
                if (!File.Exists(System.IO.Path.Combine(path, fi.Name)))
                {
                    File.Copy(fi.FullName, System.IO.Path.Combine(path, fi.Name));
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        // Get linkage between ListBox's DLL name list and the loaded plugin names
        string GetDLLName(string name)
        {
            string ret = "";

            name = name.Replace(" ", ""); // strip spaces

            Assembly asm = AppDomain.CurrentDomain.GetAssemblies().
                   SingleOrDefault(assembly => assembly.GetName().Name == name);

            if (asm != null)
            {
                ret = Path.GetFileName(asm.Location);
            }

            return ret;
        }


        private void lbFiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            AssembleComponents(sender);

        }

        private void ClearBtn_Click(object sender, RoutedEventArgs e)
        {

            lbFiles.Items.Clear();    
            _Plugins = new Dictionary<string, IPlugin>();

        }
    }
}

1 个答案:

答案 0 :(得分:0)

我只需将此函数添加到clearBtn方法

//Clears the Assembly
        this.PluginGrid.Children.Clear();

private void ClearBtn_Click(object sender, RoutedEventArgs e)
            {

                lbFiles.Items.Clear();    
                _Plugins = new Dictionary<string, IPlugin>();

            }

之后

 private void ClearBtn_Click(object sender, RoutedEventArgs e)
    {

       // Clears the ListBox
        lbFiles.Items.Clear();

        //Clears the Assembly
        this.PluginGrid.Children.Clear();

        //Loads next Assembly 
        _Plugins = new Dictionary<string, IPlugin>();

    }