Dependency Injection and Database

Feb 2, 2012 at 7:51pm
Hi,

I'm using dicpp to structure my application around dependency injection.

I need to use an SQLite database to store and retrieve a large amount of data from the object graph.

The database has a table for each class. The di graph is nested deeply so there are many objected stemming from many object all of which need to store and retrieve data from the database.

Can someone please explain the approach for interacting with a database in an IoC setup like this?

I am a music composer for a living, but I rely on my own software which I am refactoring from an almost broken state to DI where expandability and testability will be easier. This aspect has been keeping me from moving forward,
Feb 3, 2012 at 10:04pm
I've never used a dependency injection framework - feel free to ignore everything I say.

dicpp is a dependency injection framework for c++ modeled on GoogleGuice for Java, which I have never used but I understand is popular.

These frameworks are intrusive into the code, you put special things in there that the framework uses to put in the "boiler plate" of dependency injection. I notice that dicpp is currently developed by a single (undoubtably very talented) individual. I may be cynical but I usually look to see if a project has a few active members before doing something that will be spread throughout my code. If you are going to use it, then you will probably be joining the maintainers, which is great if you want to split your time to do this, but not so great if you just want to concentrate on your music.

Also, I am surprised that a single programmer project needs such heavy machinery. Why not inject your dependencies manually in the constructors? Thats what I do.

Also, this software is for your own use only? In this case many of the dependencies you want to vary in the type of software that needs to be distributed (such as platform, window system, input devices etc) will be fixed for you? You need to decide which things are going to be dependencies (things that vary now and in the future and for testing) and those that aren't. Do you need to make 'string' a dependency so that you can vary your string provider at will, or just use std::string and leave it at that?

Changing to a DI framework will not automatically fix your broken design. You still need to do that, maybe it will be easier to do that without the extra cognitive loading of learning this system?

Feb 3, 2012 at 10:41pm
Thanks for your point of view.

I am looking to build this on windows as an intermediary for iOS, which will then become my focus. I am building it for myself at the moment to use and refine, but ultimately I want to release it for mobile and as many platforms as I can.

The dependencies are on several different kinds of modular processors, like FX. These are swapped in and out by the hundreds at runtime. They return lists of values (often just a single value in length) but all functionally internally in different ways and store internal values about where they are in their cycles. The database should store their parameters but not the iterating values.

The ideas are very modular and very nested simple parameters have lists of modulators that all have parameters which have lists and so on. These are going to be sorted with Boosts topological sort. I am looking to store a large amount of information of every one of those settings across many iterations in SQLite database's and eventually also online databases.

My plan, and I am very open to being steered in a better direction, is to use dicpp, hiberlite and SQLite, to build the basic scaffolding that can look up data calculate new data and put it in the right place in the database. There will be many sections stored in the database but one DI chain will be active while the chain is running to update the modular parameters internal settings at each audioblock. I am using a crossplatform audio framework for the loop.

From there the work would be in creating implementation of the different module types and then later expanding in more significant ways when moving to iOS.

My eyes are bigger than my stomach I have endless plans but I need to get the software that I currently have running in its minimal form as soon as I can so I can do my daily routine with it. I realize this will require a total rewrite which is why I was looking at these frameworks, to pick the most expandable, modular system and design with that in mind. I was hoping that by using a framework I would be limiting the number of errors an inexperienced programmer can make. I definitely see you point about ending up a maintainer. I've talked to him a bit but am supposed to hear back this weekend.

I checked the commit dates of every available c++ DI frame work and dicpp was the only one that was being actively maintained.

Do you have a good reference for manually injecting objects as parameters? This would involve making a factory object that created new instances of things and passed in a reference?I hear the boiler plate code bit everywhere... I not opposed to it but it feels like there is a lot that is being done that I am going to miss in winging it.

I am very interested to know if I am on the wrong path. I've been mulling over this for weeks now. I feel like I am making progress understanding this all, but I am constantly finding that I maybe be using a different framework for what my needs are. It could very well be that a hand rolled implementation suits this idea the best, but then which and I down the path of treating tutorials like frameworks, copying the examples.
Feb 4, 2012 at 1:37pm
Sounds like you have a big project planned!

You need rock solid tools when undertaking a big project. I was up late one night last week and almost convinced myself that boost::dynamic_bitset was broken. Well this is unlikely, the boost libraries are well regarded and used by thousands, so I just have to dig in and find my error. This is bad (there is some error in my program I don't understand at the moment) but also good (it is within my power to fix it). If the tools you are using are not rock solid you do not have this certainty.

Structurally, dependency injection is the same as the 'bridge pattern' (multiplied up). I do not use the factory pattern, just make a dependent object and pass it into the object that needs it in the constructor. The object needing the dependency stores a reference to the required object. For example, I am doing a graphical project where the output device could be anything. It could be a real time animation or a set of raytracer scene description files, one per scene. In the future it may be 3D animated output. So I have an abstract OutputDevice class which models this output and various concrete derived classes. To draw the scene a Render class needs an OutputDevice which it just receives as an argument in its constructor. The Renderer does not know if it is writing to the screen, a file or some 3D hardware, it just uses OutputDevice's standardised interface.

This does mean that I have some fairly lengthy constructor argument lists. I am hoping to alleviate that problem using the named parameter idiom.
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.20

So 'dependency injection' is really just a type of object composition, which is why I am not sure why your requirements are so intense. Is object composition the right way of combining the units you are chaining? Maybe they should communicate in some other way?

As regards manual dependency injection I've done a bit of googling and there are plenty of opinion pieces for and against this that or the other method of injection. There are two ways of manually injecting: "constructor injection" and "setter injection". In setter injection you provide public member functions that allow you to set the various dependencies an object may need.

In C++ you also need to decide whether to use a reference or pointer inside the class to point to the dependency. If you use a reference then you have to use constructor injection and the dependency is fixed throughout the object's lifetime. With a pointer you can use setter injection and also change the dependency.

Topic archived. No new replies allowed.