Changes all collections from collection builders to resolve the concrete instances lazily.
This means we don't have to inject Lazy<T> all over the place when dealing with colleciton builders and circular references since this will automatically just work OOTB. This in theory should also allocate less instances during startup.
This commit is contained in:
48
src/Umbraco.Core/Composing/LazyReadOnlyCollection.cs
Normal file
48
src/Umbraco.Core/Composing/LazyReadOnlyCollection.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Cms.Core.Composing
|
||||
{
|
||||
public sealed class LazyReadOnlyCollection<T> : IReadOnlyCollection<T>
|
||||
{
|
||||
private readonly Lazy<IEnumerable<T>> _lazyCollection;
|
||||
private int? _count;
|
||||
|
||||
public LazyReadOnlyCollection(Lazy<IEnumerable<T>> lazyCollection) => _lazyCollection = lazyCollection;
|
||||
|
||||
public LazyReadOnlyCollection(Func<IEnumerable<T>> lazyCollection) => _lazyCollection = new Lazy<IEnumerable<T>>(lazyCollection);
|
||||
|
||||
public IEnumerable<T> Value => EnsureCollection();
|
||||
|
||||
private IEnumerable<T> EnsureCollection()
|
||||
{
|
||||
if (_lazyCollection == null)
|
||||
{
|
||||
_count = 0;
|
||||
return Enumerable.Empty<T>();
|
||||
}
|
||||
|
||||
IEnumerable<T> val = _lazyCollection.Value;
|
||||
if (_count == null)
|
||||
{
|
||||
_count = val.Count();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureCollection();
|
||||
return _count.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator() => Value.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user