1

我无法通过反射创建插件解决方案。当我单击一个 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(单击菜单项时我想加载的程序)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 < N; Col++)
       {
           //Q toevoegen
           bord[Row, Col] = true;

           //Q + Q volgende Row  controleren
           if (bordValidatie(Row, Col, bord, N) && berekenQueens(Row + 1, N, bord))
           {
               return true;
           }

           //Q verwijderen indien niet door controle
           bord[Row, Col] = false;

       }
       return false;
   }


   private static bool bordValidatie(int currentRow, int currentCol, bool[,] currentBord, int N)
   {
       int colstep = 1;
       for (int i = currentRow - 1; i >= 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;
   }


}

主窗口(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 方法?

4

2 回答 2

2

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

  • 您的核心应用程序
  • 仅包含接口的库(即 IPlugin)
  • 你的扩展。

查看codeproject以更好地了解插件的架构。

于 2013-01-26T09:39:36.633 回答
1

一个更简单的模式是带有接口的经典“工厂模式”。我之前做过这个来创建插件,它真的很简单:

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

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

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

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

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

于 2013-01-26T09:43:43.553 回答