3

I'm trying to use Simple Injector v1.6 in combination with the Unity3D game engine (v5.0).
I need to use Property Injection because Unity3D has control over the assembly and will not allow Constructor Injection, because (how unfortunate it may be) that's just the way Unity3D's API is currently.

Unity3D targets the scripting assemblies to .NET 3.5, so this means that System.ComponontModel.Composition is not available, resulting that I cannot use explicit property injection as described in the Simple Injector documentation.

So my question to the developer(s) of Simple Injector is: 'Is there any other way to utilize property injection into classes that are controlled by the Unity3D engine?'.

Steven
  • 166,672
  • 24
  • 332
  • 435
QuantumHive
  • 5,613
  • 4
  • 33
  • 55
  • Personally I'm not sure if _DI_ or their variants is a good idea for a game considering the performance overhead they typically impose. –  May 25 '15 at 14:52
  • 1
    @MickyDuncan your comment isn't really in the scope of my question. That topic is an entirely different discussion that has nothing to do with my question. – QuantumHive May 25 '15 at 15:26
  • @MickyDuncan, performance is irrelevant. Your object graph ahould consist of singletons anyway, and this makes performance of resolving your object graphs a non-issue. – Steven May 25 '15 at 17:56
  • I'm sorry. In that case my answer doesn't make any sense. Please see my update. – Steven May 26 '15 at 11:20
  • _[The answer can be “don’t do that”...](http://stackoverflow.com/help/how-to-answer)_. Reflection: _[Reflection requires a large amount of the type metadata to be loaded and then processed. This can result in a larger memory overhead and slower execution. According to this article property modification is about 2.5x-3x slower and method invocation is 3.5x-4x slower.](http://stackoverflow.com/questions/224232/what-is-the-cost-of-net-reflection)_; Know what 3rd party tools are utilising: http://simpleinjector.readthedocs.org/en/latest/howto.html. Using DI for a few singletons is overkill –  May 26 '15 at 13:03
  • @Steven _"performance is irrelevant"_ - perhaps but then you will be using reflection to set the _properties_ on new objects which could be many throughout the life of the app, not just at startup. This is not an ASP.NET app but a **game** where performance is generally paramount. If _"object graph ahould consist of singletons anyway"_ I'd argue put away that DI library and use a gold ol' class factory pattern. Considerably faster; less complex; less dependencies (no punintended); less impact on GC. I certainly wouldn't want DI running on a mobile device –  May 26 '15 at 13:06
  • 3
    @MickyDuncan: I didn't mean that perf of a game is irrelevant. But when building up an object graph with singletons, you will only have to build up this graph once and that will cause the resolve-time to become irrelevant, even if very heavy reflection is used. You are absolutely right that DI libraries use reflection. The use of external tools increase the memory footprint, and so do any jitted .NET code. But do note however that Simple Injector optimizes resolving objects by compiling and caching delegates. This means that there is a one-time cost with reflection. – Steven May 26 '15 at 13:50
  • 2
    @MickyDuncan: DI is about writing loosely coupled code. But DI is about patterns; not about tools. So it is always good to question whether a DI library is an improvement. Using factories instead of DI however doesn't result in the same amount of loose coupling. DI typically gives the most flexibility, while keeping our code simple and maintainable. Using DI might indeed be overkill if used "for a few singletons", but that is different from having *a big object graph that consist solely of singletons*. I use DI to determine how the object graph is composed when the application starts. – Steven May 26 '15 at 13:50
  • 1
    @Steven thank you Steven for the clarification. I agree and respect you. Have a good day –  May 26 '15 at 16:19
  • @MickyDuncan Just to be clear here, the part of where I want to use Simple Injector is for [extending the editor](http://docs.unity3d.com/460/Documentation/Manual/ExtendingTheEditor.html). As you might know, this part of the assembly does not affect the game performance in any way. I like to keep my code [SOLID](http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29), using a [Service Locator is an anti-pattern](http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/). The things I create aren't just a few singletons, so a DI will definitely help me with my specific use cases. – QuantumHive May 27 '15 at 09:52
  • @QuantumHive _"extending the editor"_ - oh why didn't you say so. Agreed, performance is not at issue there. :) Consider including that in your question. Thanks –  May 27 '15 at 13:03

1 Answers1

4

There are multiple ways how Simple Injector's default behaviour can be extended when it comes to property injection, but the best way is to override Simple Injector's PropertyInjectionBehavior as explained here.

You say that constructor injection is not an option. This indicates that it is impossible to intercept the creation of some framework types. The Unity3d framework is in control here.

In such situation, you will have to let Simple Injector build up existing types. Never an optimal situation, but there's probably little you can do about that. This wiki page describes how you can let Simple Injector build up external instances.

UPDATE

The answer above is specific to Simple Injector v2. Simple Injector v2 got a lot new compelling features such as the IPropertySelectionBehavior abstraction for enabling property injection, the Registration class to allow building up external instances, and the ExpressionBuilding event to allow intercepting the creation of types to allow injecting properties or fields.

Simple Injector v2 however requires .NET 4.0, so this means that using v2 is not an option for you, because you require .NET 3.5. All those features are not available in Simple Inject v1, so the answer above doesn't make sense for you.

The only option left is to use the Container.InjectProperties(object) method to allowing implicit property injection on externally created instances.

There are however many downsides to implicit property injection, as described here. That's why the InjectProperties method has been marked [Obsolete] since v2.6. The reason for this is described here. For the reasons described there, Simple Injector v3 will not even include the InjectProperties method.

So your only option is to use the InjectProperties method to build up your objects, but please read the referenced articles to understand what the risk of using implicit property injection is. Understanding the risk allows you to make an informed decision about whether this is a risk for you and allows you to apply counter measures, such as writing extra unit tests.

A completely different option, might be the use of Humble Objects. What this means is, that instead of falling back to property injection, you make this class that needs to be created by Unity3D as small as possible with as little code as possible. You move all interesting logic with all its dependencies to a custom component where constructor injection can be applied. Inside the stripped down 'humble' class, you just resolve the newly created component and use it.

This allows you to apply best practices when it comes to dependency injection, without having to fall back to ugly property injection, while keeping the untestable code to an absolute minimum.

Steven
  • 166,672
  • 24
  • 332
  • 435