Compile-time / Post-Build Dependency Injection IoC?
I currently use NInject to bind interfaces to concrete types and inject those into my classes. However, it is my understanding that this is a run-time affair. To me, it seems like a point of attack if someone wanted to change the behavior of my application.
Is there anything that would allow me to migrate my dependency injection IoC to compile time (Read: post-build IL weaving/replacement)?
In my code I setup a binding
with ctor Foo(Bar dependency)
At the root of my application (on start-up) I resolve the graph
var foo = kernel.Get
Assume I have no service locators (anti-pattern anyway right?). So I have no use for kernel anymore.
Now I want to have a “post-build release-compile” that replaces the kernel’s resolution engine with instanciators, or references to constant/singleton, etc. Such that while my code looks like this;
var foo = kernel.Get
In reality, after IL replacement in my final build stage, it looks like this:
var bar = new Bar();
var foo = new Foo(bar);
And there is no reference to NInject anymore.
My rational for this question is that I’m using Fody to IL Weave all my PropertyChanged raisers and I’m wondering whether it would be possible to do something similar for Dependency Injection.
As discussed, your cited reasons for doing this don’t add up. However, Philip Laureano (Linfu author) did a Hiro project some time back which does pre-deployment DI. No idea if it went anywhere…
From a security perspective in general, the use of a DI container does not pose any extra threats to your application.
When you write a service (such as web service or web site) application, the attacker could only change the DI configured behavior of the application when that application or server has already been compromized. When this happens, the server should be be considered lost (you will have to reformat that server or throw it away completely). DI doesn’t make this worse, since a DI container does typically not allow the behavior to be changed from the outside. You will have to do something very weird to make this happen.
For an application that runs on the user’s machine on the other hand, you should always consider that application to be compromised, since an attacker can decompile your code, change the behavior at runtime etc. Again, DI doesn’t make this worse, since you can only protect yourself against attacks on the service boundary. That client app must communicate with the server and the place to store your valuable assets is within the service boundaries. For instance, you should never store a accounts password inside a DLL on the client. No matter whether it is encrypted or not.
The use of DI however, can make it somewhat easier for an attacker to change the behavior of a client application, especially when you configure everything in XML. But that holds for everything you store in the configuration file. And if that’s your only line of defense (either with or without DI) you’re screwed anyway.
it seems like a point of attack if someone wanted to change the
behavior of my application
Please note that any application can be decompiled, changed, and recompiled. It doesn’t matter whether it’s managed (.NET, Java) or not (C++), or obfuscated or not. So again, from a security perspective it doesn’t matter whether you do runtime DI or compile-time DI. If this is an issue, don’t deploy that code on machines that you have no control over.