Exemple #1
0
        internal InjectFrame(DependencyLayer layer, int parentStackLevel, Type type)
        {
            if (parentStackLevel < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(parentStackLevel), "Cannot be negative.");
            }

            this.layer            = layer ?? throw new ArgumentNullException(nameof(layer));
            this.parentStackLevel = parentStackLevel;
            this.type             = type ?? throw new ArgumentNullException(nameof(type));
            this._disposed        = false;
        }
Exemple #2
0
 public override bool TryFetch <T>(out T dependency, bool useFallbacks)
 => _stack.Peek().dependencies.TryGetValue(typeof(T), out StackedDependency dep)
                 ? Logic.SucceedIf(
     !dep.IsNull,
     out dependency, (T)dep.Dependency
     )
                 : useFallbacks
                 ? Logic.SucceedIf(DependencyLayer.TryFetch(
                                       this.Fallback,
                                       out dependency,
                                       useFallbacks
                                       ))
                 : Logic.Fail(out dependency);
Exemple #3
0
        private static bool isParentOfLayer(DependencyLayer parent, DependencyLayer child)
        {
            var l = child;

            while (l != null)
            {
                if (l == parent)
                {
                    return(true);
                }
                l = l.Fallback;
            }
            return(false);
        }
Exemple #4
0
        internal static void CloseLayer(DependencyLayer layer)
        {
            if (layer != CurrentLayer)
            {
                LayerCloseMismatch?.Invoke(null, new LayerCloseErrorEventArgs(CurrentLayer, layer));
            }

            if (layer.Fallback == null)
            {
                // TODO: Fix that in the case of fallbacks being modified via reflection, this error message won't make sense
                throw new InvalidDIStateException(
                          "Cannot close root dependency layer (Fallback == null).",
                          DisposeExceptionsManager.WrapLastExceptionThrown()
                          );
            }

            if (!isParentOfLayer(layer, CurrentLayer))
            {
                // Layers are only created and added to the fallback-stack by calling NewLayer(),
                // and only removed by calling CloseLayer() via Dispose(), which only runs once.
                // If a layer has been added, and has not yet been disposed/closed, then it must be
                // possible to find it.
                // So if we failed to find it, reflection must have been used to either create a
                // layer without adding it, or used to modify the fallback of a layer.
                // Someones done that, throw an exception
                // TODO: Fix that in the case of fallbacks being modified via reflection, this error message won't make sense
                throw new InvalidDIStateException(
                          $"{nameof(MutatingDependencyLayer)} '{layer}' was never opened.",
                          DisposeExceptionsManager.WrapLastExceptionThrown()
                          );
            }

            // Now that we know it's safe to do so (we will eventually hit the layer to close),
            // step up from the current layer, marking each layer closed as we go, until we reach
            // the layer to close, and close it.
            var l = CurrentLayer;

            while (l != null)
            {
                if (l == layer)
                {
                    l.MarkDisposed();                     // just in case
                    _currentLayer = l.Fallback;           // close all layers below l.Fallback
                    return;
                }

                l.MarkDisposed();
                l = l.Fallback;
            }
        }
        public override DependencySnapshot Snapshot(bool useFallbacks)
        {
            if (SnapshotReady)
            {
                return(_snapshot);
            }


            var builder = ImmutableDictionary.CreateBuilder <Type, StackedDependency>();

            builder.AddRange(enumerateDependencies());

            IEnumerable <KeyValuePair <Type, StackedDependency> > enumerateDependencies()
            {
                foreach (var kvp in _dependencyStacks)
                {
                    if (kvp.Value.Count != 0)
                    {
                        yield return(new KeyValuePair <Type, StackedDependency>(
                                         kvp.Key,
                                         kvp.Value.Peek().RunOnSnapshot()
                                         ));
                    }
                }
            }

            var fb = this.Fallback;

            while (useFallbacks && fb != null)
            {
                DependencyLayer.AddAsFallbackToSnapshot(fb, builder);
                fb = fb.Fallback;
            }

            return(_snapshot = new DependencySnapshot(builder.ToImmutable()));
        }
Exemple #6
0
 internal DependencyLayer(DependencyLayer fallback)
 {
     this.Fallback = fallback ?? throw new ArgumentNullException(nameof(fallback));
 }
Exemple #7
0
 private protected static void AddAsFallbackToSnapshot(
     DependencyLayer fallback,
     ImmutableDictionary <Type, StackedDependency> .Builder snapshotBuilder
     ) => fallback.AddAsFallbackToSnapshot(snapshotBuilder);
Exemple #8
0
 internal Disposer(DependencyLayer layer) => this.Layer = layer;
Exemple #9
0
 internal SafeDependencyLayer(DependencyLayer fallback) : base(fallback)
 {
 }
Exemple #10
0
 public static DependencyLayer.Disposer NewLayer()
 {
     _currentLayer = new MutatingDependencyLayer(fallback: CurrentLayer);
     return(new DependencyLayer.Disposer(_currentLayer));
 }
 internal MutatingDependencyLayer(DependencyLayer fallback) : base(fallback)
 {
 }
 public LayerCloseErrorEventArgs(DependencyLayer currentLayer, DependencyLayer layerToClose)
 {
     this.CurrentLayer = currentLayer;
     this.LayerToClose = layerToClose;
 }