2016-03-30 11 views
9

現在、実行時に拡張機能をロードする必要がある動的システムを開発中です。ASP MVCコアRC1は、実行時にロードされた他のアセンブリにコントローラ、ビュー、モデルを配置します

拡張子は、Controllerで終わるクラス、/ View/ControllerNameにあるビューとViewComponents、および関連するモデルで、コントローラフォルダを意味するMVCアプリケーションと同じアーキテクチャでビルドされています。

プロジェクトへの参照として、このプロジェクトを追加することはできませんので、私は、実行時にそれらをロードするミドルウェア作成:これまでのところは良い

foreach (var item in extensions) 
{ 
    Assembly.LoadFrom([email protected]"extensions\{item.Name}.dll"); 
} 

を、それらが実行時にロードされています。しかし、私が拡張機能のコントローラの1つで作成されたルートにアクセスしようとすると、WebSiteは私に404応答を返します。

私は参考としてエクステンションを追加しようとしましたが、それはうまく動作するので、これは私のエクステンション内の問題ではありません。

DLLのコントローラをMVCのメインサイトに登録する方法を教えてください。

これは、したがって、この答えは有効ではないと思われ、これはASPコアで、ASP MVC 4ではありません:依存性の注入が解決策になる可能性がasp.net mvc put controllers into a separate project

、私は私の拡張を行うための任意の解決策を見つけていません自身のためにサービスを登録してください(拡張機能の作成者にとっては複雑です)。

拡張のための私のルーティングが定義されているコントローラ側:

[Route("[controller]/[action]")] 
public class LotteryController : Controller { ... } 

私Startup.csで、私が守ってきた、実際にデフォルトルート:事実はある

app.UseMvc(routes => 
     { 
      routes.MapRoute(
       name: "default", 
       template: "{controller=Home}/{action=Index}/{id?}"); 
     }); 

が、私は私の延長をしたいです経路を有効にする:http://localhost/Lottery/Index

そして空白のページが表示されます。私の現在のindexアクションは、テスト目的のために、私の拡張プロジェクト階層

enter image description here

+0

エクステンションをロードするコードではなく、ルーティングに問題がある可能性はありますか?コントローラコードやMVCの設定をStartup.csに提供することは可能でしょうか? – lawst

+0

私の質問に追加しました – cdie

+0

あなたはデフォルトルーティングを使用しているようです。あなたはまた、 "インデックス"のコントローラメソッドを提供できますか?あなたはまたあなたの質問で "View/ControllerName"と述べましたが、デフォルトのビューディレクトリ構造は "Views/ControllerName"でなければならないので、ビューが正しい場所にあることも確認できますか? – lawst

答えて

7

MVCが自動的に起動時にControllerから継承し、それらを含めるコントローラを見つけるでしょう

// GET Index 
public IActionResult Index() 
{ 
    return Content("From extension"); 
    //return View(); 
} 

であり、ここでです。これは外部アセンブリでは機能しますが、静的にリンクされているアセンブリでのみ有効です。

MVCを動的にロードする場合は、MVCの起動を遅らせるか、アセンブリを別々に登録することができます。

このコードスニペットでは、コントローラの他のアセンブリを検索する方法を示します。これを説明している全文はhereです。アセンブリを読み込んでMVCにコントローラを強制的に検索させると、これを使用することができます。

services.AddMvc().AddControllersAsServices(new[] 
{ 
    typeof(MyController).Assembly, 
    typeof(ExternalPocoController).Assembly 
}); 

これはコントローラ用のアセンブリを検索します。唯一の警告は、が関連するビューを見つけることができないことです。私は正直なところWebAPIコントローラーでこれをやっただけではわかりません。 編集:それはサイドノートとして

作業のビューを取得するための方法かもしれないようThisに見える、私はおそらくどちらかの古い方法を経由してルートデコレータORマッピングルートを使用してお勧めしたいです。両方を使うとトラブルのレシピのように思えます。

+0

サイドノートに応答 - 属性ルーティングを使用したいが、他のすべてのロードがロードされた後にロードしたいいくつかのルートがある場合があります。 Area Routingを経由してルーティングすると、Attribute Routingよりもはるかに制御が可能になるため、属性ルーティングのすべてが処理された後にロードする4つのルート(数百)があります。 http://stackoverflow.com/questions/33155259/is-it-possible-to-change-order-of-routes-in-routing-table-when-using-attribute-rを参照してください。 –

1

アセンブリをロードするときに、アクションのActionDescriptorインスタンスを手動で追加する必要があります。実際にMVC6は 'Composite root'を使用し、不変のルートテーブルを作成します。あなたはDIでデフォルトをカスタムIActionDescriptorCollectionProviderを実装し、置き換えることができます。

public ActionDescriptorCollection ActionDescriptors 

リターンデフォルト(起動時にビルド)と、独自のActionDescriptorさん:

services.Replace(ServiceDescriptor.Describe(typeof(IActionDescriptorCollectionProvider), typeof(CustomActionDescriptorCollectionProvider), ServiceLifetime.Singleton)); 

とプロパティのゲッターで

。 私のソリューションでは、中間ストアを作成します。私は自分のActionDescriptorを配置します。ダイナミックアセンブリをロードし、IActionDescriptorCollectionProviderでロードします。

関連する問題