当业务逻辑组件被添加到我的一个表单/控件类中时,我尝试允许它们查询服务。例如,我的库中可能有一个ClientManager类,它封装了一些业务逻辑。它需要一个ILoginManager实例来查询它需要操作的一些数据。
具体的ILoginManager实例是在WinForms应用程序中创建的,例如作为一个单例。我希望能够将ClientManager组件拖放到窗体上,这将使ILoginManager实例自动对该组件可用。
根据我对this article on lightweight containers的理解,我可以通过使用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类来做到这一点呢?
发布于 2009-09-22 11:25:09
不要将System.IServiceProvider用于DI -它主要用于设计时使用。对于IComponent实现,VS设计器将为Site属性赋值,这使整个IServiceProvider机制能够工作,但该属性在运行时将为null,这意味着您对GetService的所有调用都将失败。
你最好使用合适的DI容器,比如Castle Windsor,StructureMap等。
https://stackoverflow.com/questions/1459474
复制相似问题