The point is the usage of DI-container in a proper way.
Add in Packages/manifest.json
to dependencies
:
"com.danand.simplecontainer": "https://github.com/Danand/SimpleContainer.git#0.6.9-package-unity"
Add in Packages/manifest.json
to dependencies
:
"com.danand.simplecontainer": "file:D:/repos/SimpleContainer/SimpleContainer.Unity/Assets"
- Add
UnityProjectRoot
component to any object in hierarchy. - Implement your own
MonoInstaller
and add it as component too. - Reference
MonoInstaller
toUnityProjectRoot
. - Run.
- Do not use
DontDestroyOnLoad()
to pass container through different scenes. UseLoadSceneMode.Single
for "immortal" objects (e.g. managers, services, etc.), andLoadSceneMode.Additive
for presentation layer (e.g. gameplay, UI, etc.). Quite good alternative is to use separateUnityProjectRoot
per each loaded scene. - Prefer constructor injection over any other. Yeah, that means less usage of
MonoBehaviour
dependencies. - Do not put dependencies on container. It will be perfect, if you did not have any
using SimpleContainer;
in your needy classes. - Use custom
Inject
attribute (example below). - You may move your installers to a separate assembly (via
.asmdef
) for stronger container usage protection.
public sealed class GameInstaller : MonoInstaller
{
public SettingsRepositoryAsset settingsRepository;
public MainMenuLayout mainMenuLayout;
public DailyGoalLayout dailyGoalLayout;
public override void Install(Container container)
{
// CUSTOM ATTRIBUTE:
container.RegisterAttribute<Project.InjectAttribute>();
// SETTINGS INSTANCES:
container.Register<ISettingsRepository>(Scope.Singleton, settingsRepository);
// UI LAYOUT REFERENCES:
container.Register(Scope.Singleton, mainMenuLayout);
container.Register(Scope.Singleton, dailyGoalLayout);
// SINGLETONES:
container.Register<ILocalizationRepository, LocalizationRepositoryFromFile>(Scope.Singleton);
container.Register<ITimeProvider, TimeProviderSystemJST>(Scope.Singleton);
}
public override Task ResolveAsync(Container container)
{
// NON-LAZY RESOLVING (order-sensitive):
container.Resolve<ILocalizationRepository>();
return Task.CompletedTask;
}
public override async Task AfterResolveAsync(Container container)
{
// Do initialization stuff or something.
}
}
If you really want to register MonoBehaviour
from the component of itself, use MonoRegistrator
.
- use separate
feature/your-feature
branch for each pull request - run
./generate-metas.sh
after adding/removing any file atSimpleContainer.Unity/Assets/SimpleContainer.Core
- you can work both with Unity and .NET Core solution
./SimpleContainer.sln
– .NET Core solution, includes NUnit test project./SimpleContainer.Unity/
– Unity project folder, contains shared code of core classes and Unity-specific implementation
- Clean up repository
- Set up CI
- Optimize resolving
- Refactor container interface