2009-02-27 4 views
4

올바르게 컨트롤러를 만들려면 구조 맵을 얻으려고합니다. DI를 사용하여 INewsService를 NewsController에 주입하고, 가지고있는 유일한 생성자를 만듭니다.ASP.NET MVC, MVCContrib, Structuremap, 컨트롤러 팩터로 작동합니까?

public class NewsController : Controller 
{ 
    private readonly INewsService newsService; 

    public NewsController(INewsService newsService) 
    { 
     this.newsService = newsService; 
    } 

    public ActionResult List() 
    { 
     var newsArticles = newsService.GetNews(); 
     return View(newsArticles); 
    } 
} 

나는 응용 프로그램을

public class Application : HttpApplication 
{ 
    protected void Application_Start() 
    { 
     RegisterIoC(); 
     RegisterViewEngine(ViewEngines.Engines); 
     RegisterRoutes(RouteTable.Routes); 
    } 

    public static void RegisterIoC() 
    { 
     ObjectFactory.Initialize(config => { 
      config.UseDefaultStructureMapConfigFile = false; 
      config.AddRegistry<PersistenceRegistry>(); 
      config.AddRegistry<DomainRegistry>(); 
      config.AddRegistry<ControllerRegistry>(); 
     }); 
     DependencyResolver.InitializeWith(new StructureMapDependencyResolver()); 
     ControllerBuilder.Current.SetControllerFactory(typeof(IoCControllerFactory));    
    } 
} 

를 시작하려면이 코드를 사용하고 그러나 Structuremap가 INewsService를 주입 할 것 같지 않습니다 나는 오류 이 객체에 대해 정의 된 매개 변수가없는 생성자 수 .

내가 무엇을 놓쳤는가?

답변

6

각 인터페이스를 개별적으로 구성 할 필요가 없도록 StructureMap에서 제공하는 "기본 규칙"메커니즘을 사용합니다.

내 Global.asax에가 (MvcContrib에서 StructureMap 공장을 사용) 위해 Application_Start에서이 라인이 있습니다 : 다음은 내가 그 일하기 위해 사용하는 코드입니다

protected void Application_Start() 
{ 
    RegisterRoutes(RouteTable.Routes); 
    ObjectFactory.Initialize(x => 
    { 
     x.AddRegistry(new RepositoryRegistry()); 
    }); 
    ControllerBuilder.Current.SetControllerFactory(typeof(StructureMapControllerFactory)); 
} 

그리고 RepositoryRegistry 클래스는 다음과 같습니다

DefaultConventionScanner 자동 ISomethingOrOther 및 SomethingOrOther의 nameing 규칙을 따라 인터페이스/클래스의 쌍을 찾습니다
public class RepositoryRegistry : Registry 
{ 

    public RepositoryRegistry() 
    { 
     Scan(x => 
     { 
      x.Assembly("MyAssemblyName"); 
      x.With<DefaultConventionScanner>(); 
     }); 

    } 

} 

은 이전 인터페이스의 구체적인 유형으로 후자 연결합니다. 당신이 그 기본 규칙 메커니즘을 사용하지 않은 경우

는, 당신은 명시 적으로이 구문을 사용하여 구체적인 유형에 각 인터페이스를 매핑하는 레지스트리 클래스에 코드를 추가합니다 :

ForRequestedType<ISomethingOrOther>().TheDefaultIsConcreteType<SomethingOrOther>(); 
+0

고마워!,이게 많은 도움이 되었어. 내 문제를 해결할 수 있었다. :) –

+0

@Erv 어떤 네임 스페이스가 Scan에 있습니까? 나는 사용 또는 참조가 누락 된 것 같습니다. – ahsteele

+0

우리가 사용하고있는 버전 (8 개월이 지났습니다. 최근 변경된 사항을 보지 않았습니다)에서 Scan은 RepositoryRegistry가 예제에서 상속 한 레지스트리 기본 클래스의 메소드입니다. –

0

뭔가를 놓치지 않는 한, 당신은 StructMap에게 INewsService에 사용할 구체적인 유형을 말하지 않습니다. 당신은 같은 것을 추가해야합니다 : 난 내 머리 위로 떨어져 정확한 구문을 모르는

TheConcreteTypeOf<INewsService>.Is<MyConcreteNewsService>(); 

,하지만 당신이 놓치고있는 것입니다. 일단 이것을 지정하면 컨트롤러에 주입 할 INewsService의 인스턴스를 알 수 있습니다.

+0

저는 INewsService와 같은 레지스트리에 모든 올바른 매핑을 추가하기 때문에 문제가 발생하지 않아야합니다. –

+0

나는 당신이 그것을 인스턴스화하고있는 코드를 보지 않을 것이다. – Micah

+0

코드를 레지스트리에 표시 할 수 있습니까? – Micah

0

ASP를. NET MVC는 현재 컨스트럭터 기반 종속성 삽입을 배제한 기본 매개 변수없는 생성자를 사용하여 컨트롤러를 인스턴스화합니다. 그렇게하기 위해서는 현재 문서가 존재하지 않지만 StructureMap (및 Castle/Spring.NET/Unity)에 대한 지원 기능이 내장 된 MvcContrib 프로젝트를 사용해야합니다 (글자 그대로 스텁 위키 페이지를 얻습니다. 좋지 않은 표시). 이 스레드의 Erv Walter 코드 샘플은 StructureMap 통합을 설정하는 방법을 보여줍니다.