2009-12-03 3 views
1

성 윈저를 처음 접해 보았습니다.Castle Windsor를 사용하여 HttpContext.Current.Request.Url을 반환하기 위해 uri 종속성을 등록하는 방법은 무엇입니까?

MVC 웹 응용 프로그램을 개발할 때 컨트롤러 중 하나에 현재 요청 URL을 알리는 데 대한 종속성이 있습니다. 그래서 내 위해 Application_Start에서 나는 WindsorContainer (아래 용기), 내 컨트롤러를 등록하고 다음 시도 ... 내 웹 응용 프로그램을 실행할 때

container.AddFacility<FactorySupportFacility>(); 

container.Register(Component.For<Uri>().LifeStyle.PerWebRequest.UsingFactoryMethod(() => HttpContext.Current.Request.Url)); 

그러나 나는 예외 내 컨트롤러를 얻을 수를 초기화 ...

는 다음과 같은 의존성을 기다리고 있습니다 :

키 (특정 키 구성 요소) - 등록되지 않은 URI입니다.

가 인스턴스화하려고 컨트롤러는 다음과 같은 서명이있다 : 내 팩토리 메소드를 실행하지 않는 몇 가지 이유를 들어

public MyController(Uri uri) 

를?

내가가 컨트롤러의 서명을 변경하지만 경우 :

public MyController(HttpContext httpContext) 

과에 등록을 변경

container.Register(Component.For<HttpContext>().LifeStyle.PerWebRequest.UsingFactoryMethod(() => HttpContext.Current)); 

그런 다음 모든 치료를 작동!

우리 유형을 등록하려고 할 때 나는 무엇이 누락 되었습니까? 그게 내게 똑같은 개념 인 것 같니? 나는 뭔가를 놓치고 있어야합니다!?

업데이트 :

좀 더 디버깅을 수행하고 열린 우리당 모두를 등록한 위의 팩토리 메소드를 사용하여 HttpContext를. 컨트롤러 생성자에 매개 변수로 두 유형을 모두 추가했습니다.

따라서 Uri과 HttpContext 유형이 모두 등록되어 있고 런타임에 현재 HttpContext에서 관련 유형을 반환하기 위해 FactoryMethods를 사용하고 있습니다. 또한 이러한 유형에 대한 종속성이있는 컨트롤러를 등록했습니다.

등록이 끝난 후 중단 점을 추가하고 모든 의존성을 저장하는 것처럼 보이는 것처럼 커널의 GraphNodes를 살펴 보았습니다. 여기있다 :

[0] : {EveryPage.Web.Controllers.BaseController}/{} EveryPage.Web.Controllers.BaseController

[1] : {EveryPage.Web.Controllers.WebpagesController}/{ EveryPage.Web.Controllers.WebpagesController}

[2] : {은 System.Web.HttpContext}/{}은 System.Web.HttpContext

[3] : {Castle.MicroKernel.Registration.GenericFactory 1[System.Web.HttpContext]}/{Castle.MicroKernel.Registration.GenericFactory 1 System.Web.HttpContext]}

[4] : {System.Uri}/{System.Uri}

[5] : {Castle.MicroKernel.Registration.GenericFactory 1[System.Uri]}/{Castle.MicroKernel.Registration.GenericFactory 1 [System.Uri]}

내 컨트롤러와 두 가지 유형을 등록한 것처럼 보이며 공장도 있습니다. 시원한.

지금은 WebpagesController로 드릴 종속 단지 (1)가 등록되어 한 번 봐 걸릴 경우 :

[0] : {은 System.Web.HttpContext}/{은 System.Web.HttpContext}

HttpContext와 Uri를 생성자에 사용하므로 등록 된 종속성이 2 개가되지 않아야합니까 ??

아이디어가 있으십니까? 내가 틀린 나무를 짖고 있니?

+0

이제 실제로 그것을 재현하려고 했으므로 실제로 버그처럼 보일 수 있습니다. 나는 그것을 재현 할 수 있었다. 좀 더 자세히 살펴보고 해결 방법 및 해결 방법을 제안하려고합니다. –

+0

이것은 정말로 흥미 롭습니다. Uri 대신에 Foo 클래스 만 사용하면 ... –

+0

나는 정말 이상하다는 것을 알고 있습니다 ... 시간을내어 주셔서 감사합니다. :) 나는 내가 미쳤다고 생각했습니다 !!! – j3ffb

답변

3

갱신 3 :

당신이 그것에 대해 쉽게 사용할 수있는 지금 윈저 트렁크에 new extension point있다.

UPDATE2 :

나는 처음부터 (잘 가지)이라고 밝혀졌습니다. 우리는 수업이지만 윈저는 그것을 원시인으로 취급합니다. 두 개 이상의 빠른 솔루션이 여전히 있습니다

  1. 랩 열린 IHasUri이나 뭐 어떤 종류와 컨트롤러에 해당 인터페이스에 대한 의존성을

    public class FooController 
    { 
        public IHasUri CurrentUri { get; set; } 
    
        public void SomeAction() 
        { 
         var currentUri = CurrentUri.GetCurrentUri(); 
         // do something with the uri 
        } 
    } 
    
  2. 윈저 당신이 돈에게 Uris가 원시적 인 것처럼 (그러나 여자처럼) 대우하고 싶지 않습니다.

당신은 그위한 IContributeComponentModelConstruction 구현해야합니다

public class UriIsAServiceNotAParameter:IContributeComponentModelConstruction 
{ 
    public void ProcessModel(IKernel kernel, ComponentModel model) 
    { 
     if (model.Service != typeof(UsesUri)) // your controller type here 
      return; 

     foreach (var constructor in model.Constructors) 
     { 
      foreach (var dependency in constructor.Dependencies) 
      { 
       if(dependency.TargetType ==typeof(Uri)) 
       { 
        dependency.DependencyType = DependencyType.Service; 
       } 
      } 
     } 
    } 
} 

을 컨테이너에 추가 :

도 이야기 윈저을 의미한다이 일의 가장 올바른 방법,있다
container.Kernel.ComponentModelBuilder.AddContributor(new UriIsAServiceNotAParameter()); 

Uris를 초기에 프리미티브로 등록하는 것이 아니라 나중에 수정하는 것이 아니라 커널의 가장 깊은 용기에 도달해야하므로 훨씬 더 많은 코드가 필요합니다. (비록 직설적이지만) 위에 설명 된 대안보다는.

+1

System.Uri는 구조체가 아니며 클래스이며 밀봉되지 않습니다. http://msdn.microsoft.com/en-us/library/system.uri.aspx –

+0

Oh my. 네가 옳아. –

+0

컨테이너에서 AddFacility를 수행했지만 커널에서는 수행하지 않았습니다. 차이점이 있습니까? 커널에 추가하면 동일한 오류가 발생합니다. 둘 다 추가하면 "동일한 키를 가진 항목이 이미 추가되었습니다."라는 메시지가 나타납니다. 내가 이해하지 못하는 것은 HttpContext에서는 잘 작동하지만 Uri에서는 정상적으로 작동하지 않는 이유입니다.나는 현재 요청 된 URL을 얻기 위해 전체 HttpContext를 전달해야한다. struct 인 경우 정의한 두 단계 솔루션이 사용 되었습니까? 뭔가 해결 방법이있는 것처럼 보입니까? 도움 주셔서 감사합니다. – j3ffb

관련 문제