Может ли инверсия управления и RAII играть вместе? - PullRequest
5 голосов
/ 10 октября 2009

Я только что прочитал об инверсии управления (IOC), и меня беспокоило, что кажется, что это делает управление памятью болью. Конечно, кажется, что ioc в основном используется в средах со сборщиком мусора (Net, Java, Scripting), в то время как моя проблема в настройках не-gc.

Меня беспокоит то, что IOC в некотором роде идет вразрез с RAII, поскольку мы отделяем время жизни ресурса от времени жизни объекта. Разве эта дополнительная сложность никого не беспокоит? И реальный вопрос, какие методы можно использовать, чтобы все прошло гладко?

Ответы [ 3 ]

3 голосов
/ 10 октября 2009

Именно по этой причине я создал свой собственный контейнер IoC, который возвращает (в C # /. NET) одноразовые упаковщики сервисов, которые при утилизации будут "делать правильные вещи" в отношении сервиса.

Будь то:

  • Ничего не делать, когда:
    • Объект не реализует IDisposable
    • Не ограничен контейнером (в этом случае контейнер будет отслеживать его и возвращать один и тот же объект более одного раза, а при удалении контейнера объект тоже будет)
    • Это не объединено
    • Это не одноэлементная область (такая же, как у контейнера, но иерархия контейнеров будет хранить сервис с одноэлементной областью в самом верхнем контейнере)
  • Утилизация службы (она имеет фабричную область применения и реализует IDisposable)
  • Верните его в бассейн

Это означает, что весь код, который использует мои сервисы, находится внутри блока using, но цель более ясна, по крайней мере для меня:

using (var service = container.Resolve<ISomeService>())
{
    service.Instance.SomeMethod();
}

в основном говорится: разрешите службу, вызовите SomeMethod для экземпляра службы и затем удалите службу.

Поскольку знание о том, распоряжаться экземпляром службы или нет, недоступно для потребителя, был либо выбор, либо просто игнорировать реализации IDisposable, либо избавляться от всех служб, которые реализуют IDisposable. Ни один не был хорошим решением для меня. Третий вариант заключался в том, чтобы обернуть экземпляр службы в объект, который знал, что делать со службой после удаления оболочки.

1 голос
/ 10 октября 2009

Да и нет.IoC не отделяет время жизни ресурса от времени жизни объекта, оно отделяет область вызова метода от времени жизни объекта - очень часто вы хотите, чтобы объект, который будет уничтожен в конце метода, существовал до тех пор, пока не будет выполнен другой вызов IoC.Таким образом, вы должны либо переместить локальные методы метода в область видимости класса, и убедиться, что ни один метод не является повторным входом, либо принять другой подход, такой как передача дополнительной «среды», позволяющей этим объектам владеть и уничтожатьв последующих вызовах метода IoC.Любой подход становится довольно сложным, если вам нужна система событий общего назначения - либо ваши модели вынуждены сами выполнять явную рекурсию и итерацию, либо ваш простой код RAII C ++ быстро становится очень сложным гнездом обратных вызовов - достаточно сложным, от которого я отказалсяна C ++ и RAII начали работать вместо kin .

0 голосов
/ 10 октября 2009

Первое, о чем я мог подумать, это SmartPointers. И шаблоны аргументов. Но я не уверен, что аргументы шаблона считаются методикой IOC, хотя я думаю, что они должны. По крайней мере, это может облегчить некоторые проблемы с МОК, но не полностью продано по идее.

...