将容器/内核注入主应用程序演示者是否正确?

时间:2014-03-31 04:40:00

标签: winforms dependency-injection ninject mvp

我正在使用Ninject来处理我的依赖项。

我的ApplicationPresenter负责在整个应用程序中调用用户调用功能,因此需要一次注入多个工厂,因此需要注册容器本身。它处理MDI GUI。

  1. 有更好的方法吗?
  2. 可以这样做吗?
  3. ApplicationPresenter

    public class ApplicationPresenter 
        : Presenter<IApplicationView>
        , IApplicationPresenter {
        public ApplicationPresenter(IApplicationView view, IKernel dependencies) 
            : base(view) {
            Dependencies = dependencies;
            View.Connect += OnConnect;
            View.ManageInquiries += OnManageInquiries;
        }
    
        private static readonly IKernel Dependencies;
    }
    

    ApplicationPresenter负责在MDI窗口中编排系统的功能,例如:

    1. 用户身份验证
    2. 管理查询......
    3. 我有AuthenticationPresenterInquiryManagementPresenter这两个都应该从ApplicationPresenter调用,如此:

      用户点击...

      public class ApplicationPresenter : ... { 
          // See ctor for event subscription...
      
          private void OnConnect() {
              AuthenticationPresenter authentication = 
                  Dependencies.Get<IAuthenticationPresenter>();
              authentication.ShowView();
          }
      
          private void OnManageInquiries() {
              InquiriesManagementPresenter inquiriesManagement = 
                  Dependencies.Get<IInquiriesManagementPresenter>();
              inquiriesManagement.ShowView();
          }
      }
      

      InquiriesManagementPresenter内,我依赖其他演示者:

      • NewInquiryPresenter
      • EditInquiryPresenter
      • CancelInquiryPresenter
      • ApproveInquiryPresenter ...

      Ninject模块

      public class ApplicationModule : NinjectModule {
          public void Load() {
              Bind<IApplicationPresenter>().To<ApplicationPresenter>().InSingletonScope();
              Bind<IApplicationView>().To<ApplicationForm>();
          }
      }
      
      public class AuthenticationModule : NinjectModule {
          public void Load() {
              Bind<IMembershipService>().To<MembershipService>();
              Bind<IAuthenticationPresenter>().To<AuthenticationPresenter>().InSingletonScope();
              Bind<IAuthenticationView>().To<AuthenticationForm>();
              Bind<ICredentials>().To<Credentials>().InSingletonScope();
              Bind<IUser>().To<User>().InSingletonScope();
              Bind<IDatabaseInstance>().To<DatabaseInstance>().InSingletonScope();
              Bind<IDatabaseUser>().To<DatabaseUser>().InSingletonScope();
          }
      }
      
      public class InquiryManagementModule : NinjectModule {
          public void Load() {
              Bind<INewInquiryPresenter>().To<NewInquiryPresenter>().InSingletonScope();
              Bind<INewInquiryView>().To<NewInquiryForm>();
              Bind<IEditInquiryPresenter>().To<EditInquiryPresenter>().InSingletonScope();
              Bind<IEditInquiryView>().To<EditInquiryForm>();
              Bind<IInquiryRepository>().To<InquiryRepository>();
              // ...
          }
      }
      

      因此,我发现将Ninject的IKernel从演示者传递到另一个人更简单,因为那些需要InquiryManagementPresenterApplicationPresenter等多种功能。

      所以,这还可以,还是有另一种更好的方法来实现这个目标?

1 个答案:

答案 0 :(得分:2)

你永远不应该传递DI容器,因为那时你将它用作Service Locator, which is an anti-pattern

如果您的ApplicationPresenter 要求 AuthenticationPresenterInquiriesManagementPresenter,请注入这些依赖项:

public class ApplicationPresenter : Presenter<IApplicationView>, IApplicationPresenter
{
    private readonly static AuthenticationPresenter authenticationPresenter;
    private readonly static InquiriesManagementPresenter inquiriesManagementPresenter;

    public ApplicationPresenter(
        IApplicationView view,
        AuthenticationPresenter authenticationPresenter,
        InquiriesManagementPresenter inquiriesManagementPresenter) 
        : base(view)
    {
        this.authenticationPresenter = authenticationPresenter;
        this.inquiriesManagementPresenter = inquiriesManagementPresenter;
        View.Connect += OnConnect;
        View.ManageInquiries += OnManageInquiries;
    }
}

如果这些演示者有自己的依赖关系,那就完全没问题了:你只是build up the entire graph up front,但AplicationPresenter不必看到任何子图。