1

プラグインアーキテクチャに基づいてWindowsサービスを構築していますが、問題が発生しました。問題は、プラグインがメインアプリケーションでイベントを発生させることです。ここにいくつかのコードがあります。

これらは代表者です

namespace eTreasury.SchedulerInterface
{
    public enum Severity
    {
        Message,
        Warning,
        Error
    }

    public delegate void ErrorHandler(string message, Severity errorSeverity);
    public delegate void CompletedHandler(string message);
    public delegate void ProgressReportHandler(string message, int percentCompleted);
}

これはインターフェースです

public interface IPluginInterface : IDisposable
    {
        string Identifier{ get; }

        void Run();
        void Dispose();

        event ErrorHandler OnError;
        event CompletedHandler OnCompleted;
        event ProgressReportHandler OnProgress;
    }

これは、すべてのプラグインから継承したい基本クラスです

public abstract class BasePlugin : MarshalByRefObject, IPluginInterface
{
    protected string _identifier;
    public string Identifier
    {
        get { return _identifier; }
    }

    public abstract void Run();

    protected void ReportError(string message, Severity errorSeverity)
    {
        if (OnError != null)
            OnError(message, errorSeverity);
    }
    protected void ReportProgress(string message, int percentCompleted)
    {
        if (OnProgress != null)
            OnProgress(message, percentCompleted);
    }
    protected void ReportProgress(string message)
    {
        ReportProgress(message, 0);
    }
    protected void ReportCompleted(string message)
    {
        if (OnCompleted != null)
            OnCompleted(message);
    }

    public void Dispose()
    {
        OnError = null;
        OnCompleted = null;
        OnProgress = null;
        _identifier = null;
    }

    public event ErrorHandler OnError;
    public event CompletedHandler OnCompleted;
    public event ProgressReportHandler OnProgress;
}

これはプラグインです

public class CurrencyRatesPlugin : BasePlugin
{
    public CurrencyRatesPlugin()
    {
        _identifier = "CurrencyRatesPlugin";
    }

    public override void Run()
    {
        try
        {
           ReportProgress("bla", 0);
        }
        catch (Exception e)
        {
            ReportError("bla");
        }
    }
}

そしてこれは私のWindowsサービスコードです

public partial class CurrencyRatesPluginService : ServiceBase
    {
        AppDomain appDomain;
        IPluginInterface pluginInterface;
        System.Timers.Timer Timer = null;

        public CurrencyRatesPluginService()
        {
            InitializeComponent();
        }

        protected override void OnStart(string[] args)
        {
           try
            {
                this.appDomain = CreateAppDomain();
                this.pluginInterface = (IPluginInterface)appDomain.CreateInstanceFrom("C:\\eTreasuryScheduler\\Plugins\\eTreasury.CurrencyRatesPlugin.dll", "eTreasury.Plugins.CurrencyRatesPlugin.CurrencyRatesPlugin").Unwrap();

                PluginSection section = (PluginSection)ConfigurationManager.GetSection("PluginSectionGroup/PluginSection");
                if (section == null)
                {
                    EventLogManager.LogError("bla");
                }
                else
                {
                    Timer = new System.Timers.Timer();
                    Timer.Enabled = false;
                    Timer.Interval = section.PluginItems[0].Interval;
                    Timer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_Elapsed);
                    Timer.Start();
                }
            }
            catch(Exception ex)
            {
                EventLogManager.LogError(String.Format("{0}...{1}", ex.Message, ex.InnerException == null ? string.Empty : ex.InnerException.Message));
            }
        }

        protected override void OnStop()
        {
            Timer.Stop();
            this.pluginInterface.Dispose();
            AppDomain.Unload(this.appDomain);
        }

        void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Process();
        }

        void Process()
        {
            try
            {
                this.pluginInterface.OnProgress += ProcessProgressReportHandler;
                this.pluginInterface.OnCompleted += ProcessCompletedHandler;

                pluginInterface.Run();

                this.pluginInterface.OnProgress -= ProcessProgressReportHandler;
                this.pluginInterface.OnCompleted -= ProcessCompletedHandler;
            }
            catch (Exception ex)
            {
                EventLogManager.LogError(String.Format("{0}...{1}", ex.Message, ex.InnerException == null ? string.Empty : ex.InnerException.Message));
            }
        }

        private void ProcessProgressReportHandler(string message, int percentCompleted)
        {
            EventLogManager.LogInformation(message);
        }

        private void ProcessCompletedHandler(string message)
        {
            EventLogManager.LogInformation(message);
        }

        AppDomain CreateAppDomain()
        {
            ...
        }
    }

そして、イベントを除いて、everythigは正常に機能しています。ここでエラーが発生します

this.pluginInterface.OnProgress += ProcessProgressReportHandler;

そして、エラーメッセージは

Exception has been thrown by the target of an invocation....Could not load file or assembly 'eTreasury.SchedulerService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
4

1 に答える 1

1

プラグイン インターフェイスに IHost インターフェイスと Initialize メソッドを追加しました。ホスト アプリケーションでプラグインをロードするときに、そのプラグインの Initialize メソッドを呼び出して、Host を渡します。この後、プラグインからホスト メソッドを呼び出すことができます。

于 2012-10-22T09:25:26.270 に答える