Example #1
0
        private void uninjectDependency_internal(Type type, int frameStackLevel)
        {
            if (!_dependencyStacks.TryGetValue(type, out var stack))
            {
                throw new InjectFrameCloseException(
                          $"No dependency stack for type '{type}' is available.",
                          DisposeExceptionsManager.WrapLastExceptionThrown()
                          );
            }

            if (stack.Count == 0)
            {
                throw new InjectFrameCloseException(
                          $"No dependency stack frames for type '{type}' are available.",
                          DisposeExceptionsManager.WrapLastExceptionThrown()
                          );
            }

            StackedDependency toRemove = stack.Peek();

            if (toRemove.StackLevel != frameStackLevel)
            {
                throw new InjectFrameCloseException(
                          $"Top element of stack for type '{type}' has stack level '{toRemove.StackLevel}' " +
                          $"but frame to be closed has a different stack level: '{frameStackLevel}'.",
                          DisposeExceptionsManager.WrapLastExceptionThrown()
                          );
            }

            markSnapshotDirty();
            stack.Pop();
        }
Example #2
0
        // TODO: Ensure that toMatchAgainst isn't a generic type definition, open constructed generic type,
        // generic type parameter, etc. Or maybe it can be??
        private void addToStack_internal(object dependency, Type toMatchAgainst)
        {
            var toPush = new StackedDependency(currentStackLevel + 1, dependency);

            // Must only call RunOnInject() AFTER checking to throw any exceptions.
            // Must also only call it BEFORE any lasting changes are made, in case it throws an exception.
            // TODO: Check if there's built-in exceptions that could occur, and check that there's no
            // possible lasting changes. OutOfMemoryException etc is probably OK, but need to think it through.

            if (_dependencyStacks.TryGetValue(toMatchAgainst, out var stack))
            {
                if (stack.Peek().StackLevel == currentStackLevel + 1)
                {
                    throw new InvalidOperationException(
                              $"Cannot inject dependency against type '{toMatchAgainst.FullName}' " +
                              $"as there is already a dependency present against the same type at the current stack level " +
                              $"(stack level = '{currentStackLevel + 1}'). Most likely cause: calling a method to inject multiple " +
                              $"dependencies at the same time (i.e. at the same stack level), but requesting to add two or " +
                              $"more dependencies against the same type, or more than one wildcard dependency. This would " +
                              $"result in an ambiguity for what object should be returned when the dependencies are fetched " +
                              $"(in the case of wildcards, attempting to fetch a dependency against type 'object' or any other " +
                              $"common parent type would cause this ambiguity). Instead, this is disallowed. Consider " +
                              $"injecting the dependencies one at a time so that they have a defined priority order. " +
                              $"Otherwise, if you do need multiple of the same dependency type T to be fetched as a group, " +
                              $"consider using Inject() and Fetch() with a T[], List<T>, or some other collection. If you need " +
                              $"inner code to both Fetch() the group and Fetch() just the first element (for example) then inject" +
                              $"e.g. both the List<T> and the instance of T."
                              );
                }

                toPush.RunOnInject();

                markSnapshotDirty();
                stack.Push(toPush);
            }
            else
            {
                toPush.RunOnInject();

                markSnapshotDirty();
                _dependencyStacks.Add(toMatchAgainst, new SearchableStack <StackedDependency> {
                    toPush
                });
            }
        }