/// <summary> /// Visits the children of the <see cref="T:System.Linq.Expressions.MethodCallExpression"/>. /// </summary> /// <returns> /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. /// </returns> /// <param name="node">The expression to visit.</param> protected override Expression VisitMethodCall(MethodCallExpression node) { if (node.Method.Name == nameof(IBinding <TInterface> .Resolve) && typeof(IBinding).IsAssignableFrom(node.Method.DeclaringType)) { ConstantExpression indexConstant = ((node.Object as UnaryExpression)?.Operand as BinaryExpression)?.Right as ConstantExpression; if (indexConstant != null) { int index = (int)indexConstant.Value; Type bindingType = dependencies[index].GetType(); if (bindingType.IsGenericType) { Type genericTypeDefinition = bindingType.GetGenericTypeDefinition(); Type lazyConstructorType = typeof(ILazyConstructorBinding <>); if (genericTypeDefinition.Implements(lazyConstructorType) || genericTypeDefinition == lazyConstructorType) { var dep = dependencies[index]; var dependencyResolver = new DependencyInliner((IBinding[])dep.GetPropertyValue(nameof(LazyConstructorBinding <TInterface> .Dependencies))); return(dependencyResolver.InlineDependenciesImpl( (Expression)(dep.GetPropertyValue( nameof(LazyConstructorBinding <TInterface> .ConstructionExpression)) .GetPropertyValue(nameof(Expression <Func <TInterface> > .Body)) ) )); } } } } return(base.VisitMethodCall(node)); }
/// <summary> /// Creates a new <see cref="IConstructorBinding{TInterface}"/> from the expression and dependencies contained in this object. /// </summary> /// <returns></returns> /// <exception cref="InvalidOperationException"></exception> protected virtual IConstructorBinding <TInterface> BuildConstructor() { if (Dependencies == null) { throw new InvalidOperationException(string.Format(MustBeSetBeforeUseFormat, nameof(Dependencies))); } if (ConstructionExpression == null) { throw new InvalidOperationException(string.Format(MustBeSetBeforeUseFormat, nameof(ConstructionExpression))); } // Look through each dependency and inline it if possible var inliner = new DependencyInliner(Dependencies.ToArray()); return(new ConstructorBinding <TInterface>(inliner.InlineDependencies(ConstructionExpression.Body).Compile())); }