Files
dungeons/Assets/Plugins/Zenject/Source/Providers/CachedProvider.cs

112 lines
2.9 KiB
C#

using System;
using System.Collections.Generic;
using ModestTree;
namespace Zenject
{
[NoReflectionBaking]
public class CachedProvider : IProvider
{
readonly IProvider _creator;
List<object> _instances;
#if ZEN_MULTITHREADING
readonly object _locker = new object();
#else
bool _isCreatingInstance;
#endif
public CachedProvider(IProvider creator)
{
_creator = creator;
}
public bool IsCached
{
get { return true; }
}
public bool TypeVariesBasedOnMemberType
{
get
{
// Should not call this
throw Assert.CreateException();
}
}
public int NumInstances
{
get
{
#if ZEN_MULTITHREADING
lock (_locker)
#endif
{
return _instances == null ? 0 : _instances.Count;
}
}
}
// This method can be called if you want to clear the memory for an AsSingle instance,
// See isssue https://github.com/svermeulen/Zenject/issues/441
public void ClearCache()
{
#if ZEN_MULTITHREADING
lock (_locker)
#endif
{
_instances = null;
}
}
public Type GetInstanceType(InjectContext context)
{
return _creator.GetInstanceType(context);
}
public void GetAllInstancesWithInjectSplit(
InjectContext context, List<TypeValuePair> args, out Action injectAction, List<object> buffer)
{
Assert.IsNotNull(context);
#if ZEN_MULTITHREADING
lock (_locker)
#endif
{
if (_instances != null)
{
injectAction = null;
buffer.AllocFreeAddRange(_instances);
return;
}
#if !ZEN_MULTITHREADING
// This should only happen with constructor injection
// Field or property injection should allow circular dependencies
if (_isCreatingInstance)
{
var instanceType = _creator.GetInstanceType(context);
throw Assert.CreateException(
"Found circular dependency when creating type '{0}'. Object graph:\n {1}{2}\n",
instanceType, context.GetObjectGraphString(), instanceType);
}
_isCreatingInstance = true;
#endif
var instances = new List<object>();
_creator.GetAllInstancesWithInjectSplit(context, args, out injectAction, instances);
Assert.IsNotNull(instances);
_instances = instances;
#if !ZEN_MULTITHREADING
_isCreatingInstance = false;
#endif
buffer.AllocFreeAddRange(instances);
}
}
}
}