Как использовать реализацию локатора служб в System.ComponentModel для внедрения зависимостей в приложении WinForms? - PullRequest
2 голосов
/ 22 сентября 2009

Я пытаюсь разрешить моим компонентам бизнес-логики запрашивать сервисы, когда они добавляются в один из моих классов формы / управления. Например, в моей библиотеке может быть класс 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, который удобен для разработчиков?

1 Ответ

2 голосов
/ 22 сентября 2009

Не используйте System.IServiceProvider для DI - он в основном предназначен для использования во время разработки. Для реализаций IComponent конструктор VS назначит значение свойству Site, которое позволяет всему механизму IServiceProvider работать, но это свойство будет нулевым во время выполнения, что означает, что все ваши вызовы GetService будут терпеть неудачу .

Вам лучше использовать соответствующий DI-контейнер, такой как Castle Windsor, StructureMap и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...