2

我试图让我的业务逻辑组件在添加到我的表单/控件类之一时查询服务。例如,我的ClientManager库中可能有一个类,它封装了一些业务逻辑。它需要一个ILoginManager实例来查询它需要操作的一些数据。

具体ILoginManager实例在 WinForms 应用程序中创建,例如作为单例。我希望能够将ClientManager组件拖放到表单上,这将使该ILoginManager实例自动对组件可用。

根据我从这篇关于轻量级容器的文章中了解到的,我可以通过使用 GetService 来实现这一点:

public class ClientManager : Component
{
   public ClientManager() {}
   public ClientManager(IContainer container) { 
       container.Add(this);
   } 

   public ILoginManager User 
   {
      // would really be cached in a private field
      get { return GetService(typeof(ILoginManager)) as ILoginManager; }
   }

   // does something that requires the User property to be set
   public void DoSomething(); 
}

然后,我将拥有一个覆盖 GetService 以返回我的实例的容器:

public class MyContainer : Container
{
    ServiceContainer svc;

    public MyContainer() {
        svc = new ServiceContainer();
        svc.AddService(typeof(ILoginManager), GlobalAppStuff.LoginManager);
    }

    protected override object GetService(Type service) {
        return svc.GetService(service);
    }
}

作为一个独立的解决方案,它工作得很好,但我不知道如何将它集成到一个可设计的控件中,因为设计器总是生成一个默认System.ComponentModel.Container容器,我不知道有什么方法可以将服务注入其中。

MSDN 文档在描述如何实际使用这些概念方面含糊其辞。是否有任何直接的方法可以使用设计人员友好的 ComponentModel 类来做到这一点?

4

1 回答 1

2

不要将 System.IServiceProvider 用于 DI - 它主要用于设计时使用。对于 IComponent 实现,VS 设计器将为 Site 属性分配一个值,这使整个 IServiceProvider 机制能够工作,但该属性在运行时将为空,这意味着您对 GetService 的所有调用都将失败.

最好使用适当的 DI 容器,例如 Castle Windsor、StructureMap 等。

于 2009-09-22T11:25:08.777 回答