How to use service locator implementation in System.ComponentModel for dependency injection in WinForms application?

I am trying to allow business logic components to request services when they are added to one of my form / control classes. For example, I might have a class ClientManager

in my library that encapsulates some business logic. The instance ILoginManager

requires a query for some data that it needs to use.

A concrete instance ILoginManager

is created in a WinForms application, for example, as a singlet. I would like to be able to drop a component ClientManager

into a form, which will make the instance ILoginManager

available to the component automatically.

From what I understand from this article on lightweight containers , I could achieve this using 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(); 
}

      

I would then have a container that overrides GetService to return my instance:

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);
    }
}

      

As a standalone solution, this works great, but I can't figure out how to integrate it into a constructive control as the designer always creates a System.ComponentModel.Container

default container and I don't know how to inject services into it.

The MSDN documentation is unclear in describing how these concepts should actually be used. Is there an easy way to do this using the ComponentModel classes that are designer friendly?

+2


source to share


1 answer


Don't use System.IServiceProvider for DI - it is intended primarily for use in development mode. For IComponent implementations, the VS constructor assigns a value to the Site property, which allows the entire IServiceProvider to work, but this property will be null at runtime, which means that all your GetService calls will fail.



You would be better off using the correct DI container like Castle Windsor, StructureMap, etc.

+2


source







All Articles