Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can inversion of control and RAII play together?

I was just reading up on inversion of control (IOC) and it bothered me that it seems like it makes memory management a pain. Of course it seems ioc is mostly used in garbage collected environments (Net,Java,Scripting), while my concern is in non-gc settings.

My concern here is that IOC in a way goes against RAII, as we decouple resource lifetime from object lifetime. Doesn't this added complexity bother anyone else? And the real question, what techniques can be used to make things go smoothly?

like image 410
Robert Gould Avatar asked Oct 10 '09 15:10

Robert Gould


People also ask

When would you use an Inversion of Control?

Inversion of control serves the following design purposes: To decouple the execution of a task from implementation. To focus a module on the task it is designed for. To free modules from assumptions about how other systems do what they do and instead rely on contracts.

What application factor does Inversion of Control help lessen in spring?

Inversion of control is a practical way to reduce code duplication, and if you find yourself copying an entire method and only changing a small piece of the code, you can consider tackling it with inversion of control.

What is Inversion of Control IoC and dependency injection?

Spring IoC (Inversion of Control) Container is the core of Spring Framework. It creates the objects, configures and assembles their dependencies, manages their entire life cycle. The Container uses Dependency Injection(DI) to manage the components that make up the application.

Is IoC a framework?

The IoC container is a framework used to manage automatic dependency injection throughout the application, so that we as programmers do not need to put more time and effort into it. There are various IoC Containers for .


2 Answers

For this very reason I've made my own IoC container which returns (in C#/.NET) disposable service wrappers, that when disposed of, will "do the right thing" in regards to the service.

Be it:

  • Do nothing, when:
    • The object does not implement IDisposable
    • Is not container-scoped (in which case the container will keep track of it and return the same object more than once, and when the container is disposed of, the object will be too)
    • It is not pooled
    • It is not singleton-scoped (same as container-scoped, but a hierarchy of containers will store the singleton-scoped service in the topmost container)
  • Dispose of the service (it has factory scope, and implements IDisposable)
  • Return it to the pool

This means that all code that uses my services is inside a using-block, but the intent is more clear, at least to me:

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

basically it says: resolve a service, call SomeMethod on the service instance, and then dispose of the service.

Since knowledge of whether to dispose of the service instance or not isn't available to the consumer, there was either the choice of just ignoring IDisposable implementations altogether, or to dispose of all services which implement IDisposable. Neither was a good solution to me. The third choice was to wrap the service instance in an object that knew what to do with the service once the wrapper was disposed of.

like image 58
Lasse V. Karlsen Avatar answered Nov 10 '22 03:11

Lasse V. Karlsen


Yes and no. IoC doesn't decouple resource lifetime from object lifetime, it decouples method invocation scope from object lifetime - you very often want object which would be destroyed at the end of a method to exist until another IoC call is made. So you either have to move the locals of a method into class scope, and ensure no method is re-entrant, or adopt another approach, such as having an extra 'environment' passed around to allow objects to be owned by that, and destroyed in subsequent IoC method calls. Either approach gets quite complicated if you want a general purpose event driven system - either your models end up having to implement explicit recursion and iteration themselves, or your simple RAII C++ code rapidly becomes a very complex nest of callbacks - sufficiently complex that I gave up on C++ and RAII started working on kin instead.

like image 1
Pete Kirkham Avatar answered Nov 10 '22 05:11

Pete Kirkham