修改
This commit is contained in:
parent
722dc7c251
commit
58baa6269e
@ -15,7 +15,34 @@ namespace AlicizaX
|
|||||||
typeof(IServiceOrder),
|
typeof(IServiceOrder),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Cache for the common no-extraContracts path — contracts per concrete type never change.
|
||||||
|
private static readonly Dictionary<Type, List<Type>> _contractCache = new Dictionary<Type, List<Type>>();
|
||||||
|
|
||||||
public static List<Type> Collect(Type serviceType, IReadOnlyList<Type> extraContracts)
|
public static List<Type> Collect(Type serviceType, IReadOnlyList<Type> extraContracts)
|
||||||
|
{
|
||||||
|
if (extraContracts == null || extraContracts.Count == 0)
|
||||||
|
{
|
||||||
|
if (_contractCache.TryGetValue(serviceType, out var cached))
|
||||||
|
return cached;
|
||||||
|
var result = BuildContracts(serviceType);
|
||||||
|
_contractCache[serviceType] = result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extra contracts path: build fresh, validate, append extras.
|
||||||
|
var contracts = BuildContracts(serviceType);
|
||||||
|
contracts = new List<Type>(contracts); // don't mutate the cached list
|
||||||
|
var unique = new HashSet<Type>(contracts);
|
||||||
|
for (var i = 0; i < extraContracts.Count; i++)
|
||||||
|
{
|
||||||
|
var extraContract = extraContracts[i];
|
||||||
|
ValidateExtraContract(serviceType, extraContract);
|
||||||
|
if (unique.Add(extraContract)) contracts.Add(extraContract);
|
||||||
|
}
|
||||||
|
return contracts;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Type> BuildContracts(Type serviceType)
|
||||||
{
|
{
|
||||||
var contracts = new List<Type> { serviceType };
|
var contracts = new List<Type> { serviceType };
|
||||||
var unique = new HashSet<Type> { serviceType };
|
var unique = new HashSet<Type> { serviceType };
|
||||||
@ -28,16 +55,6 @@ namespace AlicizaX
|
|||||||
if (ExcludedContracts.Contains(contract)) continue;
|
if (ExcludedContracts.Contains(contract)) continue;
|
||||||
if (unique.Add(contract)) contracts.Add(contract);
|
if (unique.Add(contract)) contracts.Add(contract);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extraContracts == null) return contracts;
|
|
||||||
|
|
||||||
for (var i = 0; i < extraContracts.Count; i++)
|
|
||||||
{
|
|
||||||
var extraContract = extraContracts[i];
|
|
||||||
ValidateExtraContract(serviceType, extraContract);
|
|
||||||
if (unique.Add(extraContract)) contracts.Add(extraContract);
|
|
||||||
}
|
|
||||||
|
|
||||||
return contracts;
|
return contracts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -154,10 +154,11 @@ namespace AlicizaX
|
|||||||
var service = snapshot[i];
|
var service = snapshot[i];
|
||||||
if (!_contractsByService.ContainsKey(service)) continue;
|
if (!_contractsByService.ContainsKey(service)) continue;
|
||||||
RemoveFromLifecycleLists(service);
|
RemoveFromLifecycleLists(service);
|
||||||
RemoveBindings(service);
|
RemoveContractBindings(service); // skip _registrationOrder.Remove — we clear below
|
||||||
service.Destroy();
|
service.Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_registrationOrder.Clear();
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,6 +207,17 @@ namespace AlicizaX
|
|||||||
_registrationOrder.Remove(service);
|
_registrationOrder.Remove(service);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used during full Dispose — skips the O(n) _registrationOrder.Remove since we clear the list afterwards.
|
||||||
|
private void RemoveContractBindings(IService service)
|
||||||
|
{
|
||||||
|
if (_contractsByService.TryGetValue(service, out var contracts))
|
||||||
|
{
|
||||||
|
for (var i = 0; i < contracts.Count; i++)
|
||||||
|
_servicesByContract.Remove(contracts[i]);
|
||||||
|
}
|
||||||
|
_contractsByService.Remove(service);
|
||||||
|
}
|
||||||
|
|
||||||
private IServiceTickable[] GetTickSnapshot()
|
private IServiceTickable[] GetTickSnapshot()
|
||||||
{
|
{
|
||||||
if (_tickablesDirty)
|
if (_tickablesDirty)
|
||||||
|
|||||||
@ -61,9 +61,6 @@ namespace AlicizaX
|
|||||||
// DefaultExecutionOrder 会影响所有生命周期(含 Awake),用 Start 可彻底规避执行顺序陷阱。
|
// DefaultExecutionOrder 会影响所有生命周期(含 Awake),用 Start 可彻底规避执行顺序陷阱。
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
if (_dontDestroyOnLoad)
|
|
||||||
DontDestroyOnLoad(gameObject);
|
|
||||||
|
|
||||||
OnAwake();
|
OnAwake();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,6 +75,11 @@ namespace AlicizaX
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Defer DontDestroyOnLoad until after the duplicate check so rejected
|
||||||
|
// duplicates are never moved to the DontDestroyOnLoad scene.
|
||||||
|
if (_dontDestroyOnLoad)
|
||||||
|
DontDestroyOnLoad(gameObject);
|
||||||
|
|
||||||
scope.Register(this);
|
scope.Register(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user