예제 #1
0
 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 + "\"")))));
 }
예제 #2
0
        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));
        }
예제 #4
0
        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);
        }
예제 #6
0
        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));
        }
예제 #7
0
        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);
        }
예제 #9
0
        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)));
        }
예제 #10
0
        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 }));
        }
예제 #11
0
        private Expression GenerateParameterizedLambdaExpressionInjectionFactoryMethodCallExpression(TypeRegistration registration)
        {
            var parameterizedFactory = (ParameterizedLambdaExpressionInjectionFactoryMethodCallExpression)registration.Factory;

            return(parameterizedFactory.Resolve(this.parameterExpressionsByType));
        }
예제 #12
0
        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()))));
        }
예제 #13
0
 private Expression GenerateInjectionFactoryMethodCallExpression(TypeRegistration registration)
 {
     var injectionFactory = (InjectionFactoryMethodCallExpression)registration.Factory;
     return injectionFactory.Resolve(this.container);
 }
예제 #14
0
        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);
        }
예제 #15
0
 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 + "\""))));
 }
예제 #16
0
 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);
     }
 }
예제 #18
0
 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);
 }