private Expression GenerateThrowUnconstructableExpression(TypeRegistration registration) { return (Expression.Throw( Expression.Constant( new ArgumentException( string.Format( "Attempted to construct an interface or abstract class of Type \"" + registration.MappedToType + "\""))))); }
private void AddParameterizedDependants(TypeRegistration item, List <TypeRegistration> registrations) { var factory = item.Factory as ParameterizedLambdaExpressionInjectionFactoryMethodCallExpression; if (factory != null) { foreach (var type in factory.DependentTypes) { TypeRegistration typeRegistration = this.TypeRegistrationResolver(type); this.AddParameterizedDependants(typeRegistration, registrations); registrations.Add(typeRegistration); } } }
private Expression GenerateFactoryExpression(ParameterExpression variable, TypeRegistration registration) { var factoryType = registration.Factory.GetType(); Expression resolvedExpression = factoryType == typeof(InjectionFactoryMethodCallExpression) ? this.GenerateInjectionFactoryMethodCallExpression(registration) : registration.Factory; if (factoryType == typeof(ParameterizedInjectionFactoryMethodCallExpression)) { var parameterizedFactory = (ParameterizedInjectionFactoryMethodCallExpression)registration.Factory; return parameterizedFactory.Resolve(registration.RegistrationType, variable, this.codeExpressions, this.parameterExpressionsByType); } if (factoryType == typeof(ParameterizedLambdaExpressionInjectionFactoryMethodCallExpression)) { var parameterizedLambdaFactory = (ParameterizedLambdaExpressionInjectionFactoryMethodCallExpression)registration.Factory; return parameterizedLambdaFactory.Resolve(registration.RegistrationType, variable, this.codeExpressions, this.parameterExpressionsByType); } return Expression.Assign(variable, Expression.TypeAs(resolvedExpression, registration.RegistrationType)); }
private Expression GenerateFactoryExpression(ParameterExpression variable, TypeRegistration registration) { Expression resolvedExpression; var factoryType = registration.Factory.GetType(); if (factoryType == typeof(ParameterizedLambdaExpressionInjectionFactoryMethodCallExpression)) { resolvedExpression = this.GenerateParameterizedLambdaExpressionInjectionFactoryMethodCallExpression(registration); } else if (factoryType == typeof(ResolutionContextParameterExpression)) { resolvedExpression = this.ResolutionContextParameter; } else { resolvedExpression = registration.Factory; } return(Expression.Assign(variable, Expression.TypeAs(resolvedExpression, registration.RegistrationType))); }
private Expression GenerateExpressionForParameterConstructor(ParameterExpression variable, TypeRegistration typeRegistration) { ConstructorInfo constructor = typeRegistration.MappedToType.GetLongestConstructor(); var ctorParams = constructor.GetParameters(); if (ctorParams.Length == 0) { return Expression.Assign(variable, Expression.New(constructor)); } var body = new List<Expression>(); var variables = new List<ParameterExpression>(); foreach (var ctorParam in ctorParams) { variables.Add(this.parameterExpressionsByType[ctorParam.ParameterType].Pop()); body.Add(this.codeExpressions.Pop()); } body.Add(Expression.Assign(variable, Expression.New(constructor, variables))); return Expression.Block(body); }
public Expression Generate() { var body = new List <Expression>(); for (int i = 0; i < this.registrations.Count; ++i) { bool finalExpression = this.registrations.Count - 1 == i; ParameterExpression variable = this.parameterExpressions[i]; TypeRegistration registration = this.registrations[i]; Type type = registration.RegistrationType; Type lifetimeType = registration.LifetimeManager.GetType(); if (this.parameterExpressionsByType.ContainsKey(type)) { this.parameterExpressionsByType[type].Push(variable); } else { var s = new Stack <ParameterExpression>(); s.Push(variable); this.parameterExpressionsByType.Add(type, s); } var coreFetchExpression = this.GenerateFetchExpression(variable, registration, finalExpression); var lifetimeLookupCall = Expression.Call(Expression.Constant(registration.LifetimeManager, lifetimeType), lifetimeType.GetRuntimeMethods().Single(x => x.Name == "GetValue")); var fetchExpression = Expression.Block(coreFetchExpression, this.GenerateSetValueCall(variable, registration), variable); var equalsExpression = Expression.Equal(Expression.Assign(variable, Expression.TypeAs(lifetimeLookupCall, registration.RegistrationType)), Expression.Constant(null)); // last expression is special if (finalExpression) { body.Add(fetchExpression); return(Expression.Block(this.parameterExpressions, Expression.Condition(equalsExpression, Expression.Block(body), variable))); } body.Add(Expression.Condition(equalsExpression, fetchExpression, variable)); } return(Expression.Block(this.parameterExpressions, body)); }
private Expression GenerateFetchExpression(ParameterExpression variable, TypeRegistration registration, bool finalExpression) { // Factory case if (registration.Factory != null) { return(this.GenerateFactoryExpression(variable, registration)); } /* Non registered IFoo case, we can't throw yet, because it's possible that the lifetime manager will give it to us */ if (registration.MappedToType.GetTypeInfo().IsAbstract || registration.MappedToType.GetTypeInfo().IsInterface) { return(this.GenerateThrowUnconstructableExpression(registration)); } if (!finalExpression) { return(this.GenerateResolveExpression(this.container, variable, registration)); } /* new() case and new(param ...) case */ return(this.GenerateExpressionForParameterConstructor(variable, registration)); }
private Expression GenerateFetchExpression(ParameterExpression variable, TypeRegistration registration) { // Factory case if (registration.Factory != null) { return this.GenerateFactoryExpression(variable, registration); } /* Func<T>, similar to factory methods, but we generate the Func expression as well */ if (registration.RegistrationType.GetTypeInfo().IsGenericType && registration.RegistrationType.GetGenericTypeDefinition() == typeof(Func<>)) { return this.GenerateFuncTExpression(this.container, variable, registration); } /* Non registered IFoo case, we can't throw yet, because it's possible that the lifetime manager will give it to us */ if (registration.MappedToType.GetTypeInfo().IsAbstract || registration.MappedToType.GetTypeInfo().IsInterface) { return this.GenerateThrowUnconstructableExpression(registration); } /* new() case and new(param ...) case */ return this.GenerateExpressionForParameterConstructor(variable, registration); }
private Expression GenerateResolveExpression(IQuickInjectContainer quickInjectContainer, ParameterExpression variable, TypeRegistration registration) { Type argumentType = registration.RegistrationType; MethodInfo resolve = QuickInjectContainerType.GetRuntimeMethods().Single(x => x.Name == "Resolve" && x.GetParameters().Length == 1); var containerResolveT = Expression.Call(Expression.Constant(quickInjectContainer, QuickInjectContainerType), resolve, Expression.Constant(argumentType)); return(Expression.Assign(variable, Expression.Convert(containerResolveT, argumentType))); }
private Expression GenerateSetValueCall(ParameterExpression variable, TypeRegistration registration) { LifetimeManager lifetimeManager = registration.LifetimeManager; return(Expression.Call(Expression.Constant(lifetimeManager), lifetimeManager.GetType().GetRuntimeMethods().Single(x => x.Name == "SetValue"), new Expression[] { variable })); }
private Expression GenerateParameterizedLambdaExpressionInjectionFactoryMethodCallExpression(TypeRegistration registration) { var parameterizedFactory = (ParameterizedLambdaExpressionInjectionFactoryMethodCallExpression)registration.Factory; return(parameterizedFactory.Resolve(this.parameterExpressionsByType)); }
private Expression GenerateExpressionForParameterConstructor(ParameterExpression variable, TypeRegistration typeRegistration) { ConstructorInfo constructor = typeRegistration.MappedToType.GetLongestConstructor(); var ctorParams = constructor.GetParameters(); if (ctorParams.Length == 0) { return(Expression.Assign(variable, Expression.New(constructor))); } return(Expression.Assign(variable, Expression.New(constructor, ctorParams.Select(ctorParam => this.parameterExpressionsByType[ctorParam.ParameterType].Pop())))); }
private Expression GenerateInjectionFactoryMethodCallExpression(TypeRegistration registration) { var injectionFactory = (InjectionFactoryMethodCallExpression)registration.Factory; return injectionFactory.Resolve(this.container); }
private void VisitCodeGeneration(TypeRegistration registration) { Type type = registration.RegistrationType; Type lifetimeType = registration.LifetimeManager.GetType(); ParameterExpression variable = Expression.Variable(type); if (this.parameterExpressionsByType.ContainsKey(type)) { this.parameterExpressionsByType[type].Push(variable); } else { var s = new Stack<ParameterExpression>(); s.Push(variable); this.parameterExpressionsByType.Add(type, s); } this.parameterExpressions.Add(variable); var coreFetchExpression = this.GenerateFetchExpression(variable, registration); var lifetimeLookupCall = Expression.Call(Expression.Constant(registration.LifetimeManager, lifetimeType), lifetimeType.GetRuntimeMethods().Single(x => x.Name == "GetValue")); var fetchExpression = Expression.Block(coreFetchExpression, this.GenerateSetValueCall(variable, registration), variable); var equalsExpression = Expression.Equal(Expression.Assign(variable, Expression.TypeAs(lifetimeLookupCall, registration.RegistrationType)), Expression.Constant(null)); var conditionsExpression = Expression.Condition(equalsExpression, fetchExpression, variable); this.codeExpressions.Push(conditionsExpression); }
private Expression GenerateThrowUnconstructableExpression(TypeRegistration registration) { return Expression.Throw( Expression.Constant( new ArgumentException( string.Format( "Attempted to construct an interface or abstract class of Type \"" + registration.MappedToType + "\"")))); }
private Expression GenerateSetValueCall(ParameterExpression variable, TypeRegistration registration) { LifetimeManager lifetimeManager = registration.LifetimeManager; return Expression.Call(Expression.Constant(lifetimeManager), lifetimeManager.GetType().GetRuntimeMethods().Single(x => x.Name == "SetValue"), new Expression[] { variable }); }
public void BuildRegistration(Type type) { var mappedType = this.container.GetMappingFor(type); var typeRegistration = new TypeRegistration(type, mappedType, this.container.GetLifetimeFor(mappedType), this.container.GetFactoryExpressionFor(mappedType)); if (this.Parent == null) { this.typeRegistrations = new TreeNode<TypeRegistration>(typeRegistration); this.Parent = this.typeRegistrations; } else { this.typeRegistrations = this.typeRegistrations.AddChild(typeRegistration); } }
private Expression GenerateFuncTExpression(IUnityContainer unityContainer, ParameterExpression variable, TypeRegistration registration) { Type type = registration.RegistrationType; var argumentType = type.GenericTypeArguments[0]; MethodInfo resolve = UnityContainerType.GetRuntimeMethods().Single(x => x.Name == "Resolve"); var containerResolveT = Expression.Call(Expression.Constant(unityContainer, UnityContainerType), resolve, new Expression[] { Expression.Constant(argumentType), Expression.Constant(string.Empty), Expression.Constant(EmptyResolverOverridesArray) }); var lambdaExpr = Expression.Lambda(type, Expression.Convert(containerResolveT, argumentType)); return Expression.Assign(variable, lambdaExpr); }