2012-10-19 65 views
1

我正在構建基於插件架構的Windows服務,並遇到一些問題。 問題是我想插件在主應用程序上觸發事件。這是一些代碼。基於插件架構的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"); 
     } 
    } 
} 

這是我的窗口服務代碼

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. 
+1

當MEF存在時,你爲什麼要拋出自己的插件架構? – spender

回答

1

I`ve加入IHost接口和初始化在插件接口方法的錯誤。當在主機應用程序中加載插件時,我調用該插件的Initialize方法並將Host傳遞給它。在此之後,我有能力從插件調用主機方法。