Replaced preventive circular dependency algorithm with circular dependency detection

Detection of circular dependency upon injection instead of prevention allow bindings to be much more flexible as they don't need to know their dependencies ahead of time.
This change also allowed several performance optimizations.