2016-07-06 22 views
0

Ich habe es so gemacht, dass Sie eine DLL öffnen und in eine Listbox als klickbares Element laden können, wenn Sie einmal darauf klicken, wird das Plugin geladen und Sie können das Plugin ausführen.Wie lösche ich die geladene Assembly, so dass beim erneuten Laden eines Plugins diese nicht dupliziert wird?

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.

Wie lösche ich die Versammlung zu, so dass, wenn ich ein Plugin neu zu laden, wird es nicht zu einem doppelten ??

-Code Behind:

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>(); 

     } 
    } 
} 
+2

Sie meinen entladen, dass geladene DLL? Wenn ja, konnten Sie nicht, bis Sie den GenericLoader geändert haben, um dlls in eine separate AppDomain zu laden und das Plugin-Objekt zu mesheln. –

Antwort

0

Ich hatte gerade diese Funktion der Methode clearBtn

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

Vor

private void ClearBtn_Click(object sender, RoutedEventArgs e) 
      { 

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

      } 

Nach

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>(); 

    } 
hinzufügen