Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do dependency injection in C?

Tags:

I'm looking for a good technical solution to doing DI in C.

I have seen some of the DI questions here already, but I haven't seen one with any actual examples or concrete implementation suggestions.

So, lets say we have the following situation:

We have a set of modules in c; we want to refactor those modules so that we can use DI to run unit tests and so on.

Each module effectively consists of a set of c functions:

module_function(...);

Modules depend on each other. Ie. Typically you may have a call such as:

int module1_doit(int x) {   int y = module2_dosomethingelse(x);   y += 2;   return(y); } 

What is the correct approach to DI for this?

Possible solutions seem to be:

  • (1) Using function pointers for all module functions, and when invoking a function do this (or similar):

    int y = modules->module2->dosomethingelse(x);

  • (2) Compile multiple libraries (mock, std, etc.) of with the same symbols and dynamically link in the correct implementation.

(2) seems to be the correct way of doing it, but is difficult to configure and annoyingly forces you to build multiple binaries for each unit test.

(1) Seems like it might work, but at some point your DI controller is going to get stuck in a situation where you need to dynamically invoke a generic factory function (void ( factory) (...) say) with a number of other modules that need to be injected at runtime?

Is there another, better way of doing this in c?

What's the 'right' way of doing it?

like image 779
Doug Avatar asked May 08 '11 02:05

Doug


People also ask

What is dependency injection in C?

A dependency is an object that another object depends on. Dependency Injection (or inversion) is basically providing the objects that an object needs, instead of having it construct the objects themselves. It is a useful technique that makes testing easier, as it allows you to mock the dependencies.

What is dependency injection C# simple example?

Dependency Injection (DI) is a software design pattern that allows us to develop loosely coupled code. DI is a great way to reduce tight coupling between software components. DI also enables us to better manage future changes and other complexity in our software. The purpose of DI is to make code maintainable.

Why dependency injection is used in C#?

Dependency Injection helps to reduce the tight coupling among software components. Dependency Injection reduces the hard-coded dependencies among your classes by injecting those dependencies at run time instead of design time technically.

Which tool is used for dependency injection?

NET supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies. Dependency injection in . NET is a built-in part of the framework, along with configuration, logging, and the options pattern.


2 Answers

I don't see any problem with using DI in C. See:

http://devmethodologies.blogspot.com/2012/07/dependency-injection.html

like image 165
Andrew Avatar answered Sep 21 '22 09:09

Andrew


I've concluded that there is no 'right' way of doing this in C. It's always going to be more difficult and tedious than in other languages. I think it's important, however, not to obfuscate your code for the sake of unit tests, though. Making everything a function pointer in C may sound good, but I think it just makes the code horrific to debug in the end.

My latest approach has been to keep things simple. I don't change any code in C modules other than a small #ifdef UNIT_TESTING at the top of a file for externing and memory allocation tracking. I then take the module and compile it with all dependencies removed so that it fails link. Once I've reviewed the unresolved symbols to make sure they are what I want, I run a script that parses these dependencies and generates stub prototypes for all the symbols. These all get dumped in the unit test file. YMMV depending on how complex your external dependencies are.

If I need to mock a dependency in one instance, use the real one in another, or stub it in yet another, then I end up with three unit test modules for the one module under test. Having multiple binaries may not be ideal, but it's the only real option with C. They all get run at the same time, though, so it's not really a problem for me.

like image 41
djs Avatar answered Sep 20 '22 09:09

djs