c#插件(reflection)

我在使用reflection创建插件解决方案时遇到了麻烦。 当我点击menuItem时,我想加载并在我的窗口中显示另一个程序。 我想我需要3个项目。

  1. 单击menuItem时想要加载另一个程序的客户端程序
  2. 我要加载的程序
  3. 插件类

代码客户端程序

private void nQueensToolStripMenuItem_Click(object sender, EventArgs e) { // Create an assembly object to load our classes string path = Application.StartupPath + "\\NQueens.dll"; Assembly ass = Assembly.LoadFile(path); Type objType = ass.GetType("NQueens.NQueen"); // Create an instace of NQueens.NQueen var instance = Activator.CreateInstance(objType); // public static bool berekenQueens() objType.InvokeMember("berekenQueens", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Static, null, instance, null); // private static bool bordValidatie objType.InvokeMember("bordValidatie", BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Static, null, instance, null); } 

 [AttributeUsage(AttributeTargets.Class)] public class myPluginAttribute : Attribute { private bool _bIsPlugin; public Boolean IsPlugin { get { return _bIsPlugin; } set { _bIsPlugin = value; } } private string _sDescription; public string Description { get { return _sDescription; } set { _sDescription = value; } } public myPluginAttribute(Boolean b, String desc) { IsPlugin = b; Description = desc; } } 

NQueens(我希望在点击menuitem时加载的程序)NQueens.cs

 public class NQueen { public static bool berekenQueens(int Row, int N, bool[,] bord) { if (Row >= N) return true; for (int Col = 0; Col = 0; i--) { //rechte lijn if (currentBord[i, currentCol]) return false; //linker diagonaal if (currentCol - colstep >= 0) { if (currentBord[i, currentCol - colstep]) return false; } //rechter diagonaal if (currentCol + colstep < N) { if (currentBord[i, currentCol + colstep]) return false; } colstep += 1; } return true; } } 

MainWindow(nqueens)

 public partial class MainWindow : Window { public int iN { get { return Convert.ToInt32(txtN.Text); } set { txtN.Text = "" + value; } } private bool[,] spelbord; public MainWindow() { InitializeComponent(); } private void button1_Click(object sender, RoutedEventArgs e) { spelbord = new bool[iN, iN]; NQueen.berekenQueens(0, iN, spelbord); visualise(iN, spelbord); } private void visualise(int N, bool[,] bord) { gridTekenen(); for (int row = 0; row < N; row++) { for (int col = 0; col < N; col++) { Rectangle rect = new Rectangle(); rect.Stretch = Stretch.Fill; TextBlock txtB = new TextBlock(); if (spelbord[row, col]) { SolidColorBrush mySolidColorBrush = new SolidColorBrush(); mySolidColorBrush.Color = Colors.LightGreen; rect.Fill = mySolidColorBrush; txtB.Text = "Q"; } rect.SetValue(Grid.ColumnProperty, col); rect.SetValue(Grid.RowProperty, row); txtB.SetValue(Grid.ColumnProperty, col); txtB.SetValue(Grid.RowProperty, row); gridPaneel.Children.Add(rect); gridPaneel.Children.Add(txtB); } } } private void gridTekenen() { gridPaneel.ShowGridLines = true; int grooteGrid = int.Parse(txtN.Text); RowDefinition rowDef; ColumnDefinition colDef; for (int i = 0; i < grooteGrid; i++) { rowDef = new RowDefinition(); GridLengthConverter myGridLengthConverter = new GridLengthConverter(); GridLength gl1 = (GridLength)myGridLengthConverter.ConvertFromString(150 + "*"); rowDef.Height = gl1; colDef = new ColumnDefinition(); colDef.Width = gl1; gridPaneel.RowDefinitions.Add(rowDef); gridPaneel.ColumnDefinitions.Add(colDef); } } } 

我试图让这件事起作用。 如何让我的程序显示NQueens程序? 我的客户端程序如何知道NQueen中的方法并使用它们?

编辑:我在nQueensToolStripMenuItem_Click方法中做了一些更改。 这是正确的吗? 我现在如何在窗口中显示NQueens方法?

据我所知,您需要一个通用接口,这有助于与“扩展”进行通信。 然后,您将有三个项目:

  • 您的核心申请
  • 一个只包含接口的库(即IPlugin)
  • 你的扩展。

查看codeproject以更好地了解插件的体系结构。

更简单的模式是具有接口的经典“工厂模式”。 我之前已经完成了这个以创建插件,这非常简单:

1)创建一个接口,其中包含您用来与插件“对话”的所有属性和方法。 在基本类/程序集中定义它(几乎不会)改变。

2)创建一个框架UI应用程序,它可能有一个插件接口的库存实现,也许是默认菜单,因此您可以轻松调试并使您的界面正确。

3)现在动态加载…创建一个配置字符串,列出应该加载的多个文件。 很高兴允许这是可配置的而不是硬编码路径,为了安全性,永远不会只是在路径中加载程序集,你不知道谁可以通过文件权限的后门将它们放在那里。

4)在启动时使用方法的程序集加载来遍历每个文件,一旦加载就使用reflection来查询接口,寻找你的插件接口。 存储已加载的接口/插件的集合,并根据需要使用它们。

显然,当你有一个UI时,你将有一个方法来创建子菜单项和窗口,并将其父项适当地设置为框架应用程序菜单或客户区。 然后,您将在界面上定义一些事件来处理被点击的项目等事件。 有意义的是还定义了标准的“工具”或命令界面,因此您可以以相同的方式处理菜单项和工具栏项。