Why Consider Using Autofac With Unity3D?
I think using a dependency injection framework is really valuable when you're building a complex application, and in my opinion, a game built in Unity is a great example of this. Using Autofac with Unity3D doesn't need to be a special case. I wrote a primer for using Autofac, and in it I discuss reasons why it's valuable and some of the reasons you'd consider switching to using a dependency container framework. Now it doesn't need to be Autofac, but I love the API and the usability, so that's my weapon of choice.
Building a game can result in many complex systems working together. Not only that, if you intend to build many games it's a great opportunity to refactor code into different libraries for re-usability. If we're practicing writing good code using constructor dependency passing with interfaces, then things really start to line up in favour of using a dependency injection framework.
Getting Set Up
At the end of my autofac primer article, I provided a link to the Nuget package for Autofac. You'll notice that there's a version dependency for .NET 4.5, so if you're not sure how to get Unity3D working with .NET 4.5, you'll want to check this other article of mine. It's very simple, so don't worry!
Unity3D, at the time of writing this and using version 2018.1.1f1, there's no native Nuget package support. I haven't spent too much time investigating alternatives, but not to worry. I'll explain a quick work around. The TL;DR is that we need the binaries from the Nuget package to be loaded up by Unity3D and we'll miss out on the Nuget-y-ness for now. Not a huge deal since we'll still have Autofac support!
- Start a new Visual Studio C# project
- Ensure that the .NET framework is at least 4.5 and more specifically, the version of .NET that you'd like to use in your Unity3D project
- Open up the Nuget package manager in Visual Studio
- Search for Autofac online in the package manager (it should be the same one I referred to above!)
- Add this package to your visual studio project
- Compile this visual studio project
- Assuming you built in debug, go to the output folder (which is in bindebug if you didn't change anything from default)
- In the output folder, you'll find "Autofac.dll"
- You'll want to add this into your Unity3D project's "Assets" folder
- I like nice folder hierarchies, so I'd suggest making a subfolder inside of "Assets" called "Third Party" or "Dependencies"... Something that's obvious for what it means
- Drop in the Autofac.dll file into there
- Unity3D will add a corresponding *.meta file to go along with this
using Autofac;And the namespace should resolve! If not, sometimes this takes Unity3D a refresh operation to regenerate the project file on disc, so if you switch to Unity3D again and it starts doing some processing, switching back to Visual Studio might resolve this. ## Using Autofac With Unity3D Up until this point, we've proven we can reference Autofac. I'm not going to explain all the ins and outs for how you'll want to organize your Autofac initialization in this post, but we can walk through a quick example!
- Pick a game object on your scene
- Add a new C# script to it
- Call it whatever you'd like, but make sure you know how to open it
- ... now go open it in Visual Studio :)
- We should have a method in there called Start()
- If not, feel free to add it:
-
private void Start() { // TODO: we'll add stuff here }
- Let's use this code to make a new class that you can put inside the same script file for now:
-
public sealed class MyAutofacObject {
public MyAutofacObject() { Debug.Log("Constructor for our object!"); }
public void DoThing() { Debug.Log("Test!"); } }
-
- Inside this start method, let's try doing something VERY simple to prove Autofac works!
-
var containerBuilder = new Autofac.ContainerBuilder(); containerBuilder.RegisterType<MyAutofacObject>().SingleInstance();
var container = containerBuilder.Build() var instance = container.Resolve<MyAutofacObject>();
instance.DoThing();
-
- The script attached to the game object should run
- The Start() method on the script should be the first thing that goes
- The code we added should:
- Make a new ContainerBuilder
- Register our MyAutofacObject type as a single instance
- Build the container
- Resolve an instance of our type
- Log out a message saying it's in the constructor
- Log out a message that says Test!
I'll continue to add into this Unity3D series of posts, but let me know what else you'd like to know about using Autofac with Unity3D! I'd be happy to try and answer, or even create an article to help explain.
Thanks!