プラグインをホストできる単純なアプリケーションを作成しました。
プラグインが依存サービスを提供する場合は問題ありませんが、ホスト自体を操作するプラグインを作成する場合 (たとえば、ホストの変更、BackColor
テキストの追加TextBox
など) は、解決策を見つけることができないようです!
私が試したすべての方法は、循環依存関係が原因で機能しないためです。
最初に、いくつかのパブリックを作成してホストアプリケーション内に作成しようとしましSetters
たGetters
が、それを参照として追加しようとしたときに、IpluginInterface
循環依存関係が原因
で、ホストアプリケーションのセッターとゲッターを実装するためにミドルクラスを試しました。私は同じエラーに直面しました。
このエラーを回避してホスト アプリケーションを操作するにはどうすればよいですか?
質問する
125 次
1 に答える
2
「Interfaces」という 3 番目のプロジェクトを作成し、そこにメイン アプリケーションへのインターフェイスを配置します。プラグインをインスタンス化するときは、そのインターフェイスを介してメイン アプリケーションへの参照を渡します。これにより、循環参照が防止されます。
メイン プロジェクトとプラグインはどちらも「Interfaces」プロジェクトを参照できます。
編集: これは完全なコード例です。もちろん、簡単にするためにすべてを 1 つのファイルにまとめましたが、各パーツが通常存在する場所についてのコメントを追加しました。プラグインが認識しないタイプのパラメーターについて言及しました。その場合は、単に新しいインターフェイスをインターフェイス プロジェクトに追加し、パラメーターをそのインターフェイスから派生させます。
これを実行するには、winforms プロジェクトを作成し、ロットを新しいクラスに貼り付けます。次に、古いフォームと Program.cs ファイルを削除します。
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
// This is the program start. Probably the place that would have loaded the plug ins.
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
//Form goes in project one and has a reference to Interfaces.
public class MainForm : Form, IMainForm
{
private TextBox _textBox;
private IPlugIn _thePlugIn;
private Button _aButton;
public MainForm()
{
InitializeComponent();
_thePlugIn = ObtainPlugInsThroughMagic();
}
private IPlugIn ObtainPlugInsThroughMagic()
{
// So this would usually go off and load some DLLs and then instantiate the IPlugIn objects
// We're cheating.
var plugin = new MyPlugIn();
plugin.Initialise(this);
return plugin;
}
public void SetTextBoxValueFromPlugIn(string newText)
{
_textBox.Text = newText;
}
private void InitializeComponent()
{
_textBox = new TextBox();
_aButton = new Button();
SuspendLayout();
_aButton.Location = new Point(20, 50);
_aButton.Size = new Size(100, 25);
_aButton.TabIndex = 1;
_aButton.Click += AButtonClick;
_aButton.Text = "Fire plug in";
_textBox.Location = new Point(20, 10);
_textBox.Size = new Size(260, 20);
_textBox.TabIndex = 0;
AutoScaleDimensions = new SizeF(6F, 13F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(300, 100);
Controls.Add(_textBox);
Controls.Add(_aButton);
Text = "Main form";
ResumeLayout(false);
PerformLayout();
}
private void AButtonClick(object sender, System.EventArgs e)
{
_thePlugIn.MakePlugInDoItsStuff();
}
}
#region interfaces go in the new Interfaces project.
public interface IMainForm
{
void SetTextBoxValueFromPlugIn(string newText);
}
public interface IPlugIn
{
void Initialise(IMainForm mainForm);
void MakePlugInDoItsStuff();
}
#endregion
// The plug in goes in the plug in project and has a reference to Interfaces.
public class MyPlugIn : IPlugIn
{
public IMainForm MainForm { get; private set; }
public void Initialise(IMainForm mainForm)
{
MainForm = mainForm;
}
public void MakePlugInDoItsStuff()
{
MainForm.SetTextBoxValueFromPlugIn("Text set from plug in");
}
}
}
于 2013-04-10T10:01:19.893 に答える