private void GenerateBaseExpression(ServiceBinding serviceBinding, CircularDependencyDetector circularDependencyDetector) { if (serviceBinding.BaseExpression == null) { lock (serviceBinding) { if (serviceBinding.BaseExpression == null) { ParameterExpression[] parameters = serviceBinding.Expression.GetParameterExpressions().Where(x => x.Type != ExpressionGenerator.ScopeParameter.Type).ToArray(); var factories = new InstanceFactory[parameters.Length]; for (var i = 0; i < parameters.Length; i++) { ParameterExpression parameter = parameters[i]; ServiceBinding child = GetDependency(parameter.Type).Default; factories[i] = ResolveDependency(parameter.Type, child, circularDependencyDetector); } if (serviceBinding.ResolveError != null) { throw serviceBinding.ResolveError; } serviceBinding.BaseExpression = _expressionGenerator.GenerateBaseExpression(serviceBinding, factories, _containerScope, _settings); } } } }
private void GenerateBaseExpression(ServiceBinding serviceBinding, CircularDependencyDetector circularDependencyDetector) { if (serviceBinding.BaseExpression == null) { lock (serviceBinding) { if (serviceBinding.BaseExpression == null) { if (serviceBinding.Expression == null) { var constructor = serviceBinding.ConstructorResolver.DynamicSelectConstructor(serviceBinding.ConcreteType, this); serviceBinding.Expression = serviceBinding.ConcreteType.ResolveConstructorExpression(constructor); } ParameterExpression[] parameters = serviceBinding.Expression.GetParameterExpressions().Where(x => x.Type != ExpressionGenerator.ScopeParameter.Type).ToArray(); var factories = new InstanceFactory[parameters.Length]; for (var i = 0; i < parameters.Length; i++) { ParameterExpression parameter = parameters[i]; ServiceBinding child = GetDependency(parameter.Type).Default; InstanceFactory? factory = TryResolveDependency(parameter.Type, child, circularDependencyDetector); factories[i] = factory ?? throw (child.ResolveError ?? throw new NotImplementedException()); } serviceBinding.BaseExpression = _expressionGenerator.GenerateBaseExpression(serviceBinding, factories, _containerScope, Settings); } } } }
private InstanceFactory ResolveDependency(Type type, Binding dependency, CircularDependencyDetector circularDependencyDetector) { circularDependencyDetector.Enter(type); GenerateBaseExpression(dependency, circularDependencyDetector); InstanceFactory factory = GenerateInstanceFactory(type, dependency, circularDependencyDetector); circularDependencyDetector.Leave(type); return(factory); }
private InstanceFactory GenerateInstanceFactory(Type type, ServiceBinding serviceBinding, CircularDependencyDetector circularDependencyDetector) { lock (serviceBinding) { if (!serviceBinding.TryGetInstanceFactory(type, out InstanceFactory factory)) { if (serviceBinding.Expression is AbstractBindingExpression) { factory = new InstanceFactory(type, (ExpressionContext)serviceBinding.BaseExpression !, scoped => throw new AbstractTypeResolveException($"Cannot create a instance for type {type} since its registered as a abstract binding and not meant to be used directly.")); serviceBinding.Factories.Add(factory); return(factory); } Expression[] decorators = FindDecorators(type); ParameterExpression[] parameters = decorators.GetParameterExpressions().Where(x => x.Type != ExpressionGenerator.ScopeParameter.Type && x.Type != type).ToArray(); var childFactories = new InstanceFactory[parameters.Length]; for (var i = 0; i < parameters.Length; i++) { ParameterExpression parameter = parameters[i]; ServiceBinding child = GetDependency(parameter.Type).Default; childFactories[i] = ResolveDependency(parameter.Type, child, circularDependencyDetector); } ReadOnlyExpressionContext context = _expressionGenerator.ApplyDecorators(type, serviceBinding, childFactories, decorators, _containerScope); factory = new InstanceFactory(type, context); serviceBinding.Factories.Add(factory); } return(factory); } }
private InstanceFactory?TryResolveDependency(Type type, ServiceBinding dependency, CircularDependencyDetector circularDependencyDetector) { try { Settings.Logger.Log($"{nameof(TryResolveDependency)} for {type}", circularDependencyDetector.Count); circularDependencyDetector.Enter(type); GenerateBaseExpression(dependency, circularDependencyDetector); InstanceFactory factory = GenerateInstanceFactory(type, dependency, circularDependencyDetector); return(factory); } catch (Exception e) { dependency.ResolveError = new DependencyResolveException(type, dependency, e); return(null); } finally { circularDependencyDetector.Leave(type); } }
private InstanceFactory GenerateInstanceFactory(Type type, Binding dependency, CircularDependencyDetector circularDependencyDetector) { lock (dependency) { if (!dependency.TryGetInstanceFactory(type, out InstanceFactory factory)) { Expression[] decorators = FindDecorators(type); ParameterExpression[] parameters = decorators.GetParameterExpressions().Where(x => x.Type != ExpressionGenerator.ScopeParameter.Type && x.Type != type).ToArray(); var childFactories = new InstanceFactory[parameters.Length]; for (var i = 0; i < parameters.Length; i++) { ParameterExpression parameter = parameters[i]; Binding child = GetDependency(parameter.Type).Default; childFactories[i] = ResolveDependency(parameter.Type, child, circularDependencyDetector); } Expression expression = _expressionGenerator.ApplyDecorators(type, dependency, childFactories, decorators, _containerScope); factory = new InstanceFactory(type, expression); dependency.Factories.Add(factory); } return(factory); } }