112 lines
2.9 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|