C# 基于插件体系结构的Windows服务

C# 基于插件体系结构的Windows服务,c#,windows-services,C#,Windows Services,我正在构建一个基于插件架构的windows服务,我遇到了一些问题。 问题是我希望插件在主应用程序上触发事件。下面是一些代码 这些是代表 namespace eTreasury.SchedulerInterface { public enum Severity { Message, Warning, Error } public delegate void ErrorHandler(string message, S

我正在构建一个基于插件架构的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()
        {
            ...
        }
    }
除事件外,一切正常。 错误发生在这里

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.

我在插件接口中添加了IHost接口和初始化方法。在主机应用程序中加载插件时,我调用该插件的初始化方法并将主机传递给它。在此之后,我可以从插件调用宿主方法。

我已经在插件接口中添加了IHost接口和初始化方法。在主机应用程序中加载插件时,我调用该插件的初始化方法并将主机传递给它。在此之后,我可以从插件中调用主机方法。

有没有理由在MEF存在时小跑自己的插件体系结构?有没有理由在MEF存在时小跑自己的插件体系结构?