Beispiel #1
0
        // The constructor parameter in which the factory for creating decorated instances should be injected.
        private Expression BuildExpressionForScopedDecorateeFactoryDependencyParameter(
            ParameterInfo param, Type serviceType, Expression expr)
        {
            if (DecoratorHelpers.IsScopeDecorateeFactoryDependencyParameter(param.ParameterType, serviceType))
            {
                expr = CompilationHelpers.OptimizeScopedRegistrationsInObjectGraph(this.Container, expr);

                var instanceCreator =
                    Expression.Lambda(Expression.Convert(expr, serviceType)).Compile();

                var scopeParameter = Expression.Parameter(typeof(Scope), "scope");

                // Create an Func<Scope, [ServiceType>
                var scopedInstanceCreator = Expression.Lambda(
                    Expression.Call(
                        ResolveWithinThreadResolveScopeMethod.MakeGenericMethod(serviceType),
                        scopeParameter,
                        Expression.Constant(instanceCreator),
                        Expression.Constant(this.Container)),
                    scopeParameter)
                                            .Compile();

                return(Expression.Constant(scopedInstanceCreator));
            }

            return(null);
        }
Beispiel #2
0
        protected ServiceTypeDecoratorInfo GetServiceTypeInfo(
            ExpressionBuiltEventArgs e,
            Expression originalExpression     = null,
            Registration originalRegistration = null,
            Type registeredServiceType        = null)
        {
            originalExpression    = originalExpression ?? e.Expression;
            originalRegistration  = originalRegistration ?? e.ReplacedRegistration;
            registeredServiceType = registeredServiceType ?? e.RegisteredServiceType;

            // registeredProducer.ServiceType and registeredServiceType are different when called by
            // container uncontrolled decorator. producer.ServiceType will be IEnumerable<T> and
            // registeredServiceType will be T.
            if (e.DecoratorInfo == null)
            {
                Type implementationType =
                    DecoratorHelpers.DetermineImplementationType(originalExpression, e.InstanceProducer);

                // The InstanceProducer created here is used to do correct diagnostics. We can't return the
                // registeredProducer here, since the lifestyle of the original producer can change after
                // the ExpressionBuilt event has ran, which means that this would invalidate the diagnostic
                // results.
                var producer = new InstanceProducer(
                    registeredServiceType, originalRegistration, registerExternalProducer: false);

                e.DecoratorInfo = new ServiceTypeDecoratorInfo(implementationType, producer);
            }

            return(e.DecoratorInfo);
        }
Beispiel #3
0
        private Expression BuildDecoratorEnumerableExpressionForConstantEnumerable(
            Delegate wrapInstanceWithDecoratorDelegate, IEnumerable collection)
        {
            // Build the query: from item in collection select wrapInstanceWithDecorator(item);
            IEnumerable decoratedCollection =
                collection.Select(this.registeredServiceType, wrapInstanceWithDecoratorDelegate);

            // Passing the enumerable type is needed when running in the Silverlight sandbox.
            Type enumerableServiceType = typeof(IEnumerable <>).MakeGenericType(this.registeredServiceType);

            if (this.Lifestyle == Lifestyle.Singleton)
            {
                IEnumerable CreateCollection()
                {
                    Array array = ToArray(this.registeredServiceType, decoratedCollection);

                    return(DecoratorHelpers.MakeReadOnly(this.registeredServiceType, array));
                }

                IEnumerable singleton = this.GetSingletonDecoratedCollection(CreateCollection);

                return(Expression.Constant(singleton, enumerableServiceType));
            }

            return(Expression.Constant(decoratedCollection, enumerableServiceType));
        }
Beispiel #4
0
        private Expression BuildDecoratorEnumerableExpressionForNonConstantExpression(
            Delegate wrapInstanceWithDecorator, Expression expression)
        {
            // Build the query: from item in expression select wrapInstanceWithDecorator(item);
            var callExpression =
                DecoratorHelpers.Select(expression, this.registeredServiceType, wrapInstanceWithDecorator);

            if (this.Lifestyle == Lifestyle.Singleton)
            {
                Type enumerableServiceType =
                    typeof(IEnumerable <>).MakeGenericType(this.registeredServiceType);

                IEnumerable CreateCollection()
                {
                    Type     funcType            = typeof(Func <>).MakeGenericType(enumerableServiceType);
                    Delegate lambda              = Expression.Lambda(funcType, callExpression).Compile();
                    var      decoratedCollection = (IEnumerable)lambda.DynamicInvoke();
                    Array    array = ToArray(this.registeredServiceType, decoratedCollection);

                    return(DecoratorHelpers.MakeReadOnly(this.registeredServiceType, array));
                }

                IEnumerable singleton = this.GetSingletonDecoratedCollection(CreateCollection);

                // Passing the enumerable type is needed when running in a (Silverlight) sandbox.
                return(Expression.Constant(singleton, enumerableServiceType));
            }

            return(callExpression);
        }
Beispiel #5
0
        private OverriddenParameter[] CreateOverriddenParameters(Type serviceType,
                                                                 ConstructorInfo decoratorConstructor, Expression decorateeExpression,
                                                                 InstanceProducer realProducer, ServiceTypeDecoratorInfo info)
        {
            ParameterInfo decorateeParameter = GetDecorateeParameter(serviceType, decoratorConstructor);

            decorateeExpression = this.GetExpressionForDecorateeDependencyParameterOrNull(
                decorateeParameter, serviceType, decorateeExpression);

            var currentProducer = info.GetCurrentInstanceProducer();

            if (DecoratorHelpers.IsDecorateeFactoryDependencyType(decorateeParameter.ParameterType, serviceType))
            {
                // Adding a verifier makes sure the graph for the decoratee gets created,
                // which allows testing whether constructing the graph fails.
                AddVerifierForDecorateeFactoryDependency(decorateeExpression, realProducer);

                // By adding the decoratee producer, we allow that object graph to be diagnosed.
                realProducer.AddProducerToVerify(currentProducer);

                currentProducer = this.CreateDecorateeFactoryProducer(decorateeParameter);
            }

            var decorateeOverriddenParameter =
                new OverriddenParameter(decorateeParameter, decorateeExpression, currentProducer);

            IEnumerable <OverriddenParameter> predicateContextOverriddenParameters =
                this.CreateOverriddenDecoratorContextParameters(decoratorConstructor, currentProducer);

            var overriddenParameters = (new[] { decorateeOverriddenParameter })
                                       .Concat(predicateContextOverriddenParameters);

            return(overriddenParameters.ToArray());
        }
Beispiel #6
0
 private Type GetDecorateeFactoryTypeOrNull() => (
     from parameter in this.decoratorConstructor.GetParameters()
         where DecoratorHelpers.IsScopelessDecorateeFactoryDependencyType(
         parameter.ParameterType, this.registeredServiceType) ||
     DecoratorHelpers.IsScopeDecorateeFactoryDependencyParameter(
         parameter.ParameterType, this.registeredServiceType)
     select parameter.ParameterType)
 .FirstOrDefault();
 private IEnumerable <Registration> GetDecorateeFactoryDependencies(
     KnownRelationship[] relationships)
 {
     return
         (from relationship in relationships
          where DecoratorHelpers.IsDecorateeFactoryDependencyParameter(
              relationship.Dependency.ServiceType, this.e.RegisteredServiceType)
          select relationship.Dependency.Registration);
 }
        protected ServiceTypeDecoratorInfo GetServiceTypeInfo(Expression originalExpression,
                                                              InstanceProducer registeredProducer, Func <Type, InstanceProducer> producerBuilder)
        {
            var predicateCache = this.ThreadStaticServiceTypePredicateCache;

            if (!predicateCache.ContainsKey(registeredProducer))
            {
                Type implementationType =
                    DecoratorHelpers.DetermineImplementationType(originalExpression, registeredProducer);

                var producer = producerBuilder(implementationType);

                predicateCache[registeredProducer] = new ServiceTypeDecoratorInfo(implementationType, producer);
            }

            return(predicateCache[registeredProducer]);
        }
Beispiel #9
0
        // The constructor parameter in which the factory for creating decorated instances should be injected.
        private Expression BuildExpressionForDecorateeFactoryDependencyParameter(
            ParameterInfo param, Type serviceType, Expression expr)
        {
            if (DecoratorHelpers.IsScopelessDecorateeFactoryDependencyType(param.ParameterType, serviceType))
            {
                // We can't call CompilationHelpers.CompileExpression here, because it has a generic type and
                // we don't know the type at runtime here. We need to do some refactoring to CompilationHelpers
                // to get that working.
                expr = CompilationHelpers.OptimizeScopedRegistrationsInObjectGraph(this.Container, expr);

                var instanceCreator =
                    Expression.Lambda(Expression.Convert(expr, serviceType)).Compile();

                return(Expression.Constant(instanceCreator));
            }

            return(null);
        }
Beispiel #10
0
        private void TryToApplyDecoratorOnContainerUncontrolledCollections(ExpressionBuiltEventArgs e)
        {
            if (!IsCollectionType(e.RegisteredServiceType) ||
                DecoratorHelpers.IsContainerControlledCollectionExpression(e.Expression))
            {
                // NOTE: Decorators on controlled collections will be applied by the normal mechanism.
                return;
            }

            var serviceType = e.RegisteredServiceType.GetGenericArguments()[0];

            Type decoratorType;

            if (this.MustDecorate(serviceType, out decoratorType))
            {
                this.ApplyDecoratorOnContainerUncontrolledCollection(e, decoratorType);
            }
        }
        protected static ParameterInfo GetDecorateeParameter(Type serviceType,
                                                             ConstructorInfo decoratorConstructor)
        {
            // Although we partly check for duplicate arguments during registration phase, we must do it here
            // as well, because some registrations are allowed while not all closed-generic implementations
            // can be resolved.
            var parameters = (
                from parameter in decoratorConstructor.GetParameters()
                where DecoratorHelpers.IsDecorateeParameter(parameter.ParameterType, serviceType)
                select parameter)
                             .ToArray();

            if (parameters.Length > 1)
            {
                throw new ActivationException(
                          StringResources.TypeDependsOnItself(decoratorConstructor.DeclaringType));
            }

            return(parameters.Single());
        }
Beispiel #12
0
 private IEnumerable <Registration> GetDecorateeFactoryDependencies(KnownRelationship[] relationships) =>
 from relationship in relationships
     where DecoratorHelpers.IsScopelessDecorateeFactoryDependencyType(
     relationship.Dependency.ServiceType, this.e.RegisteredServiceType)
 select relationship.Dependency.Registration;
Beispiel #13
0
 private bool DecoratorNeedsADecorateeFactory() => (
     from parameter in this.decoratorConstructor.GetParameters()
         where DecoratorHelpers.IsScopelessDecorateeFactoryDependencyType(parameter.ParameterType, this.registeredServiceType)
     select parameter)
 .Any();