asp.net mvc는 컨트롤러를 별도의 프로젝트에 넣습니다.


107

나는 asp.net mvc를 배우고 있으며 컨트롤러를 별도의 프로젝트로 이동하는 방법을 알아 내려고 노력하고 있습니다. 일반적으로 이전에 asp.net 웹 앱을 디자인했을 때 모델 용 프로젝트 하나, 로직 용 프로젝트 하나를 만든 다음 웹이있었습니다.

이제 asp.net mvc를 배우고 있으므로 비슷한 패턴을 따르고 모델과 컨트롤러를 각각 별도의 프로젝트에 배치하고 뷰 / 스크립트 / css를 웹에 남겨두기를 원했습니다. 모델 부분은 쉬웠지만 내가 이해하지 못하는 것은 별도의 프로젝트에서 컨트롤러를 "발견"하는 방법입니다. 또한 이것이 바람직한 지 알고 싶습니다. 감사!

답변:


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
감사합니다 Craig! 이것이 바로 제가 찾던 것입니다. 이 정보가 웹에도 존재합니까? 나는 그다지 운이 좋지 않고 모든 것을 검색했습니다. StackOverflow가 다시 나타납니다!
Aaron Palmer

11
동의합니다. 컨트롤러는 사용자 입력을 처리하고 모델을 조작 한 다음 뷰에 데이터를 전달합니다. 일반적으로 응용 프로그램에 매우 구체적입니다. 앱에 국한되지 않은 논리는 라이브러리 나 모델에서 더 나을 수 있습니다. 그러나 일반적으로 컨트롤러는 웹 프로젝트와 함께 있어야합니다.
Haacked dec

2
두 앱간에 동일한 오류 컨트롤러와보기가 있습니다. 두 앱에서 모두 사용할 수있는 단일 어셈블리에 이러한 기능을 포함하는 것이 좋습니다.
항해 유도

3
컨트롤러가 별도의 프로젝트에있을 때 컨트롤러를 테스트하고 IoC를 사용하는 것이 더 쉽지 않습니까? 이것이 주된 이유입니다
Samuel G

1
@Chev, 나는 그것이 어떤 차이도 만들지 않는다고 생각합니다. 컨트롤러의 테스트 가능성은 위치가 아니라 코드 작성 방법 과 더 관련이 있습니다.
Craig Stuntz

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
이것은 매우 잘 작동하지만, 나는 라우팅 오류 방지하기 위해 일부 중복 코드 제거했다
켄 맥

안녕하세요,이 유형의 프로젝트에서 라우팅을 어떻게 관리 할 수 ​​있습니까? 속성 라우팅을 사용하고 싶습니다 ...
محمد

평소처럼 속성 라우팅을 사용할 수 있습니다.
ThisGuy

2
왜 이것이 더 많은 찬성표를 가지고 있지 않은지 잘 모르겠습니다. 받아 들여진 대답보다 훨씬 더 우아하다고 생각합니다. 감사!
jleach

이것은 나를 위해 작동하지 않습니다. 이 .Net Core 또는 .Net Framework인지 알 수 있습니까?
Homayoun Behzadian

4
  • mvc 프로젝트에 대한 클래스 라이브러리를 추가하십시오.
  • 클래스에 다음 코드를 추가합니다 (For u'r Controller Code)

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

    }

  • mvc 프로젝트보기 폴더에서 Contact 폴더를 추가하고 Call.cshtml 파일을 만듭니다. 폴더보기

  • 기본 MVC 프로젝트에 클래스 라이브러리 프로젝트 참조를 추가합니다.

참고

  • 마지막으로 연락처 컨트롤러 네임 스페이스를 Route Config로 참조합니다.

RouteConfig


3
컨트롤러와 이름이 같은 네임 스페이스가 있다는 것은 약간 불행한 일입니다.
Mariusz Jamro

3

System.Web.MvcMvcWebsite와 Class Library가 동일한 System.Web.Mvc버전을 사용하도록 NuGet 참조를 업데이트 한 후 문제가 해결되었습니다.

기본 네임 스페이스를 추가 할 필요가 없습니다.


문제는 현재의 MVC 어셈블리 조립 클래스 라이브러리의 참조 MVC보다 낮은 버전이 동시에 MvcWebsite이 예외를 발생하지 않았다고했다
호마윤 Behzadian

1

내가 사용하는 가장 간단한 분리 형태는 원래 MVC 프로젝트에서 뷰를 "있는 그대로"유지하고 컨트롤러를 제거하는 것입니다. 그런 다음 새 ClassLibrary 프로젝트에서 Controller 클래스를 추가하고 Controller에서 상속되는지 확인합니다.

MVC 라우팅 엔진은 ClassLibrary의 컨트롤러에 자동으로 라우팅되며 컨트롤러는 참조가 있고 올바르게 사용하는 경우 원본 MVC 프로젝트에서 뷰를 자동으로 구성합니다.

이 아키텍처를 사용하여 기본 솔루션과 별도로 컴파일 및 배포 할 수있는 Html 보고서 모듈을 구현하고 있습니다. 마침내 나는 SSRS에서 해방되었습니다!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.