0

MVC3에서 Ninject를 사용하여 종속성 삽입을 사용하여 기존 응용 프로그램을 재 설계하려고합니다. 여기에 내가 어려움에 봉착 기존 동작의 일부입니다 (그래 나는 그것의 나쁜 알고, 그건 내가 그것을 리팩토링하기 위해 노력하고있어 이유) :MVC3 및 Ninject와의 종속성을 올바르게 주입하는 방법은 무엇입니까?

protected override void OnActionExecuting(ActionExecutingContext filterContext) 
{ 
    base.OnActionExecuting(filterContext); 

    MyUserSession userSession = filterContext.HttpContext.Session[SESSIONKEY_USER] as MyUserSession; 

    // if session empty, rebuild user information 
    if (userSession == null) 
    { 
     string userName = HttpContext.User.Identity.Name; 
     userSession = new MyUserSession(); 

     using (ADSearcher ad = new ADSearcher(ldapPath, excludeOUString.Split(','))) 
     { 
      // get basic user information from Active Directory 
      ADUserInfo aduser = MyActiveDirectorySearcher.GetUserRecord(userName); 

      // ... set several properties queries from AD... 
      userSession.propertyXYZ = aduser.propXYZ 
     } 

     // if user can proxy as another indivudual, set property 
     using (EDMContainer db = new EDMContainer()) 
     { 
      if (db.Proxies.Any(p => p.ProxyLogin == userSession.userLogin)) 
       userSession.CanProxy == true; 
     } 

     // save new user object to session 
     filterContext.HttpContext.Session[SESSIONKEY_USER] = userSession; 

     if(userSession.canProxy) 
      filterContext.Result = RedirectToAction("Proxy", "Home"); 

     return; 
    } 
} 

그래서 현재, 직접 컨트롤러 사용자가 여러 개체 : 세션, ActiveDirectorySearch, EF 데이터베이스. 하나의 메소드 인 "GetUser"가 모든 복잡성을 숨기는 클래스를 만드는 것이 더 나을 것 같지만 의존성을 주입하는 방법에 어려움을 겪고 있습니다.

SomeUserProvider 클래스를 만들면 기존 사용자 정보를 확인하기 위해 Session에 액세스해야하며 세션이 비어있는 경우 ActiveDirectorySearcher 및 Database를 사용하여 사용자 속성을 다시 작성해야합니다.

내 혼란은 컨트롤러 자체가 다른 작업 방법에서 ActiveDirectorySearcher에 액세스해야하며 다른 클래스도 동일한 데이터베이스를 사용한다는 사실을 넘어서는 혼란이 있습니다. IActiveDirSearchrer를 컨트롤러의 생성자에 삽입 한 다음 ISomeUserProvider로 전달합니다. IMyDatabase는 어떻습니까? 또한 컨트롤러 생성자에 삽입되어 전달 되었습니까?

그리고 마지막으로 임대하지는 않았지만 ISessionWrapper? 나는 세션이 논쟁의 여지가 있지만 현재 사용자가 누군지, 그리고 각 요청 (GET 및 POST) 동안 프록시가되어 있는지 추적해야합니다. 그럼, 주사를 맞으 시나요?

대답이 각각 그렇다면, 3 가지 이상의 주입 된 contstuctor 매개 변수를 갖는 것이 좋지 않습니까?

나는 내 질문이 모호 할 수 있음을 알고 있으므로 필요한 경우 명확하게 물어보십시오. 나는 모든 제안과 권고에 대해 공개적이다. 내 목표는 올바르게 수행하는 법을 배우는 것입니다.

감사합니다. 이것이 당신이 찾고있는 정확하게 경우

+1

- 좋은 일 : 아니, 당신이 할 수있는 경우 여러 종속성을 주입하는 나쁜 관행이 아니다 다른 차원에서 논리적으로 결합하지 마십시오. –

답변

3

나는 확실하지 않다, 그러나 이것은 당신이

public class YourController : Controller 
{ 
    private readonly ISessionWrapper _sessionWrapper; 
    private readonly IActiveDirSearcher _adSearcher; 
    private readonly IMyDatabase _database; 

    public YourController(ISessionWrapper sessionWrapper, 
     IActiveDirSearcher adSearcher, IMyDatabase database) 
    { 
     this._sessionWrapper = sessionWrapper; 
     this._adSearcher = adSearcher; 
     this._database = database; 
    } 

    // now all actions in this controller have a _sessionWrapper, 
    // _adSearcher and _database 
} 

그럼 당신은 당신의 주사을 바인드 할 필요가 DI

에 대한 귀하의 응용 프로그램을 리팩토링의 길을 시작할 수 있어야 Ninject way. NinjectHttpApplication에서 응용 프로그램을 하위 클래스 및이의 구현은 귀하의 질문에 설명을 한 것으로 나타났습니다 OnApplicationStartedCreateKernel

public class MvcApplication : NinjectHttpApplication 
{ 
    // ... 

    protected override void OnApplicationStarted() 
    { 
     base.OnApplicationStarted(); 

     AreaRegistration.RegisterAllAreas(); 
     RegisterGlobalFilters(GlobalFilters.Filters); 
     RegisterRoutes(RouteTable.Routes); 
    } 

    protected override IKernel CreateKernel() 
    { 
     var kernel = new StandardKernel(); 
     kernel.Bind<ISessionWrapper>().To<YourSessionWrapperImplementation>(); 
     kernel.Bind<IActiveDirSearcher>().To<YourADImplementation>(); 
     kernel.Bind<IMyDataBase>().To<YourEDMContainerIThink>(); 

     return kernel; 
    } 
} 

우선합니다. 그러나 다른 구현 (및 다른 클래스)은 이러한 구현에 따라 달라집니다. 좋은 소식 - CreateKernel의 바인딩은 앱의 다른 곳에서 누락 된 종속성을 처리합니다. 예 :

public class MyActiveDirImplementation : IActiveDirSearcher 
{ 
    private readonly IMyDatabase _database; 

    // injected automagically WOOHOO! 
    public MyActiveDirImplementation(IMyDatabase database) 
    { 
     this._database = database; 
    } 

    public ADUserInfo GetUserRecord(string username) 
    { 
     return _database.GetSomeUserRecord(username); 
    } 
} 

당신은 물론, 유사하게 구현할 수있는 당신의 ISessionWrapper 또는 IMyDatabase 나는 당신의 질문은 막연한 생각하지 않습니다

+0

예를 들어 주셔서 감사합니다. 내가 이해하지 못했던 부분이었습니다. – Shawn

관련 문제