2013-01-17 4 views
1

요청 당 생성해야하는 리포지토리가 있습니다. 이제 데이터로 채우기 위해 저장소를 사용해야하는 싱글 톤 캐싱 개체가 있지만이 개체는 Application_Start 이벤트에서 초기화되므로 요청 컨텍스트가 없습니다."요청 당"활성화 컨텍스트 ... 요청 없음

Ninject로이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

감사합니다. 현재 HttpContext으로

답변

1

는 Ninject에 확실히 당신이 응용 프로그램 시작시 의존성을 주입 할 때이 InTransientScope에있을 것 같은 객체가 InRequestScope를 바인더 제본 처리합니다 (IIS7 통합 모드에서) 응용 프로그램 시작시이 없습니다. 우리는 Ninject에의 (2.2) 소스 코드에서 볼 수 있듯이 :

/// <summary> 
/// Scope callbacks for standard scopes. 
/// </summary> 
public class StandardScopeCallbacks 
{ 
    /// <summary> 
    /// Gets the callback for transient scope. 
    /// </summary> 
    public static readonly Func<IContext, object> Transient = ctx => null; 

    #if !NO_WEB 
    /// <summary> 
    /// Gets the callback for request scope. 
    /// </summary> 
    public static readonly Func<IContext, object> Request = ctx => HttpContext.Current; 
    #endif 
} 

HttpContext.Current는 응용 프로그램 시작시 null 될 것입니다, 그래서 InRequestScope 바인더 제본 객체는 응용 프로그램 시작시는 InTransientScope를 바인더 제본되는 것과 같은 방식으로 처리됩니다.

그래서 당신은 당신의 global.asax에 가질 수 있습니다

protected override Ninject.IKernel CreateKernel() 
{ 
    var kernel = new StandardKernel(); 
    kernel.Bind<RequestScopeObject>().ToSelf().InRequestScope(); 
    kernel.Bind<SingletonScopeObject>().ToSelf().InSingletonScope(); 
    return kernel; 
} 

protected override void OnApplicationStarted() 
{ 
    AreaRegistration.RegisterAllAreas(); 
    RegisterRoutes(RouteTable.Routes); 
    // init cache 
    this.Kernel.Get<SingletonScopeObject>().Init(); 
} 

을하지만 RequestScopeObject의 사용 후 정리를해야 할 것 (예를 들어 Dispose() 그것은, 그것은 IDisposable를 구현하는 경우). 이 같은 바인딩 조건을 활용하여 RequestScopeObject 모두 InRequestScopeInSingletonScope 바인딩

public class SingletonScopeObject 
{ 
    private string cache; 
    private RequestScopeObject requestScopeObject; 
    public SingletonScopeObject(RequestScopeObject requestScopeObject) 
    { 
     this.requestScopeObject = requestScopeObject; 
    } 

    public void Init() 
    { 
     cache = this.requestScopeObject.GetData(); 
     // do cleanup 
     this.requestScopeObject.Dispose(); 
     this.requestScopeObject = null; 
    } 

    public string GetCache() 
    { 
     return cache; 
    } 
} 

또 다른 방법

: 초기화 후

kernel.Bind<SingletonScopeObject>() 
     .ToSelf() 
     .InSingletonScope() 
     .Named("singletonCache"); 
// as singleton for initialization 
kernel.Bind<RequestScopeObject>() 
     .ToSelf() 
     .WhenParentNamed("singletonCache") 
     .InSingletonScope(); 
// per request scope binding 
kernel.Bind<RequestScopeObject>() 
     .ToSelf() 
     .InRequestScope(); 

정리는 동일합니다.

+0

그게 "아마도 걱정할 것"이라고 생각하십니까? – vtortola

+0

몇 가지 설명과 함께 "아마도"확실히 "바뀔 것입니다". ;-) 그러나 두 번째 접근법을 시도해 볼 수 있습니다.이 접근법은 Ninject 소스 코드에 대한 불필요한 통찰력없이 더욱 분명합니다. – mipe34

+0

두 번째 접근 방식이 더 효과적입니다. 나는 그것을 시도 할 것이다. 감사 :) – vtortola

관련 문제