YairHalberstadt / stronginject

compile time dependency injection for .NET
MIT License
849 stars 24 forks source link

Add Unity3D example (similar to examples of Zenject) #34

Open dzmitry-lahoda opened 4 years ago

YairHalberstadt commented 4 years ago

What do you mean by a unity example?

dzmitry-lahoda commented 4 years ago

i can do it, but only if i again will get to Unity3D project, not so soon so.

YairHalberstadt commented 3 years ago

Unity doesn't currently support Source Generators: https://forum.unity.com/threads/source-generators-via-roslyn-analyzers-in-2020-2.1003386/

I will put this on hold until that happens.

upscalebaby commented 3 years ago

Looking forward to this, evidently Unity has a stretch goal for 2021.2 to make source generators available so fingers crossed.

KuraiAndras commented 2 years ago

Once this is merged, and the new version is out you can create a Untiy sample https://github.com/xoofx/UnityNuGet/pull/77 Using StrongInject requires unity 2021.2 and later

YairHalberstadt commented 2 years ago

Do you have a link to the examples of zenject? I can't find them...

Blackclaws commented 2 years ago

Two ways to get them:

  1. Download latest release, they are in the optional extras folder once you import the package in unity https://github.com/modesttree/Zenject/releases
  2. This folder in the source, see the two folder Samplegame1 and SampleGame2 https://github.com/modesttree/Zenject/tree/master/UnityProject/Assets/Plugins/Zenject/OptionalExtras

I think what's mainly interesting is to see the stronginject version of the Installers: https://github.com/modesttree/Zenject/tree/master/UnityProject/Assets/Plugins/Zenject/OptionalExtras/SampleGame2%20(Advanced)/Scripts/Installers

as this is where the actual Bindins happen. The main issue with Unity is probably the Binding to existing scene objects (which should be possible with Container Properties/fields), the injection of existing objects in the scene as well as the creation of new objects that need to be injected afterwards.

The problem is that Unity MonoBehaviours do not support constructor injection at all. Those need to be added by the Unity System and then initialized afterwards.

I'm pretty sure its already possible to do all those things with StrongInject right now most likely through custom factories for MonoBehaviours/Prefabs.

YairHalberstadt commented 2 years ago

I gave it a try, but I have zero experience with unity, and it looks like you need to use the unity editor to work with unity projects. I don't think it's an effective use of my time to learn unity just for this, so if someone who's more familiar with unity wants to go for it, that would be great!

KuraiAndras commented 2 years ago

I have experience with DI in unity, I even wrote a library for this (https://kuraiandras.github.io/Injecter/documentation/injecter.unity.html). The problem is that in Unity the root classes that you create are inheriting from MonoBehaviour and you can't use new with them, also you can't use their constructors - so constructor injection will not work with them. In my library (similar to zenject) I solved the problem by using attributes on fields and properties, and setting them at runtime. The problem is that as far as I understand this is not possible with stronginject. In fact, I tried to create a sample with stronginject, but I could not solve this problem.

Blackclaws commented 2 years ago

If I have a bit of spare time I might try to hack something together.

Kurai is right that MonoBehaviours need injecting via functions, I think that this can be achieved via strong injects methods/properties behaviour though/factories.

It would be interesting to know whether there is any mechanism that StrongInject would directly support that allows injecting already created objects via some Inject function.

There is also no issue with having a manual root MonoBehaviour and then building a class hierarchy of standard classes from there.