Domanda

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)?


To Elaborate

In my code I setup a binding

Bind<IFoo>().To<Foo>()
Bind<Bar>().ToSelf().InSingletonScope();

with ctor Foo(Bar dependency)

At the root of my application (on start-up) I resolve the graph

var foo = kernel.Get<IFoo>();

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<IFoo>();

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.

È stato utile?

Soluzione 2

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...

Altri suggerimenti

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.

I am working on a compile time IOC container for .Net utilizing source generators:

https://github.com/YairHalberstadt/stronginject

https://www.nuget.org/packages/StrongInject/

With it you can do the following:

using StrongInject;

[Registration(typeof(Foo), typeof(IFoo))]
[Registration(typeof(Bar), Scope.SingleInstance)]
public class Container : IContainer<IFoo> {}

public static class Program
{
    public static void Main()
    {
        new Container().Resolve(foo => //use foo here);
    }
}

This will give you compile time errors and warnings if it can't resolve IFoo and avoids use of reflection.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top