2017-12-15 10 views
1

WebApiプロジェクトでMEFを使用して、binフォルダ以外のフォルダにあるプラグインを読み込みます。その後MEFを使用してプラグインを読み込むときにHangfireを使用するには?

var directoryCatalog = new DirectoryCatalog(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins")); 

var container = new CompositionContainer(directoryCatalog); 
container.ComposeParts(); 

IList<IPlugin> plugins = container.GetExportedValues<IPlugin>().ToList(); 

私が実行してプラグインを設定してい::

plugins[0].Startup(logService, unitOfWork); 

注:私は既存のインスタンスを使用していますので、私は上記の依存関係を渡すために[ImportingConstructor]を使用していない私は、次の操作を行いますすでにコントローラでインスタンス化されています。

次のようにその後、私は仕事をスケジュール:Hangfireは、ジョブを開始しようとしたとき

BackgroundJob.Schedule(() => plugins[0].Start(), new TimeSpan(0, 0, 1)); 

はしかし、私は次の例外を取得:

は、ファイルまたはアセンブリをロードできませんでした「App.Pluginsを.FirstPlugin、Version = 1.0.0.0、Culture = neutral、PublicKeyToken = null 'またはその依存関係の1つ。システムは、指定されたファイルを見つけることができません。

このようなシナリオでMEFとハングファイアを併用することは可能ですか?はいの場合は、正しい手順は何ですか?

注:プラグインDLLがメインアプリケーションと同じbinフォルダにある場合、Hangfireは正常に動作します。しかしこれは、別のプラグインフォルダを持つという目的を破っています。

答えて

1

あなたはhangfire(というか - .NET自体を)導くために必要AppDomain.AssemblyResolveイベント(hangfireサーバを起動する前に、どこか)に加入することにより、このアセンブリの場所のために:

var pluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins"); 
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { 
    var asmName = new AssemblyName(args.Name); 
    var plugin = Path.Combine(pluginPath, asmName.Name + ".dll"); 
    if (File.Exists(plugin)) 
     return Assembly.LoadFrom(plugin); 
    return null; 
}; 

あなたのプラグインがすでに実際にロードされているので、現在のアプリケーションドメインに(MEFによる)、次のようにも動作するはずです(と私は上記よりも良いかもしれないと思う):hangfireは、データベースの状態からプラグインのインスタンスをデシリアライズするために必要です

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { 
    var asmName = new AssemblyName(args.Name); 
    var existing = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(c => c.FullName == asmName.FullName); 
    if (existing != null) { 
     return existing; 
    } 
    return null; 
}; 

は、を使用していますはアセンブリの修飾名を提供していますが、この質問には関係しない複雑な問題があるため - Type.GetTypeは既にMEFによって現在のアプリケーションドメインに読み込まれているにも関わらず、プラグインアセンブリが見つかりません少し。

+0

私は上記のコードを 'Global.asax'の' Application_Start'の中に置きました。それでも同じ問題があります。 –

+0

@ Ivan-MarkDebonoは、 'pluginPath'を使用する)第1のコードブロックを試して、' Application_Start'の最初のステートメントとして配置します。 – Evk

+0

@ Ivan-MarkDebono私はまた、(プラグインパスを使用しない)2番目のコードブロックを修正しました。これは 'Application_Start'でも動作するはずです。 – Evk

関連する問題