asp.net mvcはコントローラーを別のプロジェクトに配置します


107

私はasp.net mvcを学習しているだけで、コントローラーを別のプロジェクトに移動する方法を理解しようとしています。通常、以前にasp.net Webアプリを設計したことがあるときは、モデル用に1つのプロジェクトを作成し、ロジック用にもう1つのプロジェクトを作成しました。

今私はasp.net mvcを学習しているので、同様のパターンに従ってモデルとコントローラーをそれぞれ独自のプロジェクトに配置し、views / scripts / cssをWebに残すことを望んでいました。モデルの部分は簡単でしたが、私が理解していないのは、別のプロジェクトのコントローラーを「見つけられる」ようにする方法です。また、これが望ましいかどうかも知りたいです。ありがとう!

回答:


92

まず第一に、モデルを別のプロジェクトに入れることは確かに良い考えです。あなたが発見したように、これは取るに足らないことです。

コントローラーとビューに関しては、特定のアプリケーションで特定の必要があるかもしれませんが、ほとんどの基本的なプロジェクトでそれらを分離する明らかな利点はありません。

これを行うことを選択した場合、コントローラを見つける方法をフレームワークに通知する必要があります。これを行う基本的な方法は、独自のControllerFactoryを提供することです。DefaultControllerFactoryのソースコードを見て、これがどのように行われるかを知ることができます。このクラスのサブタイプを作成し、GetControllerType(string controllerName)メソッドをオーバーライドするだけで、目的を達成できます。

独自のカスタムControllerFactoryを作成したら、global.asaxのApplication_Startに次の行を追加して、フレームワークに検索場所を指示します。

ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory());

アップデート:読むこの記事 、それはより多くの情報のためにリンクの記事を。以下についてのその投稿に関するPhil Haackのコメントも参照してください。

ControllerBuilder.Current.DefaultNamespaces.Add(
    "ExternalAssembly.Controllers");

...これは完全な解決策ではありませんが、単純なケースでは十分な可能性があります。


2
クレイグ、ありがとう!これはまさに私が探していたものです。この情報はウェブ上にも存在しますか?あまり運が悪いので、ずっと探し回っています。StackOverflowが再び登場します!
Aaron Palmer、

11
同意します。コントローラーはユーザー入力を処理し、モデルを操作して、データをビューに渡します。これらは通常、アプリケーションに固有のものです。アプリに固有ではないロジックは、ライブラリまたはモデルの方が適している場合があります。しかし、一般的にコントローラーはWebプロジェクトと一緒にあるべきです。
2008

2
2つのアプリ間で同じエラーコントローラーとビューがあります。両方のアプリが使用できる単一のアセンブリにそれらを含めることは、私には理にかなっています。
柔道

3
コントローラーが別のプロジェクトにある場合、コントローラーをテストしてIoCを使用する方が簡単ではありませんか。それが主な理由です
Samuel G

1
@シェブ、私はそれがそこにどんな違いをもたらすとは思わない。コントローラーのテスト容易性は、コントローラーがどこにあるかではなく
Craig Stuntz、2010

19

独自のControllerFactoryを作成することは妥当ですが、各プロジェクトですべてのコントローラーを定義する方が便利ですが、共有プロジェクトのコントローラーから派生させます。

namespace MyProject1.Controllers
{
   public class MyController : MySharedProject.Controllers.MyController
   {
      // nothing much to do here...
   }
}

namespace MySharedProject.Controllers
{
   public abstract class MyController : System.Web.Mvc.Controller
   {
      // all (or most) of my controller logic here...
   }
}

これには、プロジェクトごとに異なるコントローラーロジックを配置する場所があるという追加の利点があります。また、コントローラーは標準の場所に存在するため、他の開発者がコントローラーロジックをすばやく見つけやすくなります。

これが賢明かどうかに関しては、絶対にそうだと思います。ビジネスロジックが大きく異なるプロジェクト間で共有したいいくつかの共通のアカウント管理ロジックを作成しました。私は自分のアカウントと管理コントローラーを共有していますが、他のコントローラーはそれぞれのプロジェクトに固有です。


1
これは非常にうまく機能しましたが、ルーティングエラーを防ぐために冗長なコードをいくつか削除する必要がありました
Ken Mc

こんにちは、このタイプのプロジェクトでルーティングを管理するにはどうすればよいですか?私は...属性のルーティングを使用したい
محمد

通常どおりに属性ルーティングを使用できます。
ThisGuy 2017年

2
なぜこれが賛成票を持たないのかわからない...受け入れられた回答よりもはるかにエレガントだと思います。ありがとう!
jleach

これは私にはうまくいきません。これが.Net Coreか.Net Frameworkかわかりますか?
Homayoun Behzadian

4
  • mvcプロジェクトのクラスライブラリを追加します。
  • クラスに次のコードを追加します(u'r Controller Codeの場合)

    namespace ContactController
    {
    public class ContactController : Controller
    {
        public ActionResult Call()
        {
            ViewBag.Title = "Inside MyFirst Controller.";
            return View();
        }
    }

    }

  • mvcプロジェクトビューフォルダーで、連絡先のフォルダーを追加し、Call.cshtmlファイルを作成します。 フォルダを表示

  • クラスライブラリプロジェクト参照をメインのMVCプロジェクトに追加します。

参照

  • 最後に、連絡先コントローラーの名前空間をRoute Configに参照します。

RouteConfig


3
コントローラと同じ名前の名前空間があることは少し残念です。
Mariusz Jamro 2016年

3

System.Web.MvcNuGetリファレンスを更新した後で問題が解決し、MvcWebsiteとクラスライブラリが同じものを使用するようになりましたSystem.Web.Mvcバージョンを

デフォルトの名前空間を追加する必要はありません


問題は、現在のmvcアセンブリのバージョンがクラスライブラリの参照されているmvcアセンブリよりも低い間、MvcWebsiteが例外をスローしなかったということでした
Homayoun Behzadian 'Ju

1

私が使用する最も簡単な分離形式は、元のMVCプロジェクトでビューを「そのまま」保持し、コントローラーを削除することです。次に、新しいClassLibraryプロジェクトにControllerクラスを追加し、それらがControllerから確実に継承されるようにします。

MVCルーティングエンジンは自動的にClassLibraryのコントローラーにルーティングし、コントローラーは参照と使用が正しく行われていれば、元のMVCプロジェクトからビューを自動的に構築します。

このアーキテクチャを使用して、メインソリューションとは別にコンパイルおよび展開できるHTMLレポートモジュールを実装しています。ついに私はSSRSから解放されました!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.