// 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); }
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); }
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)); }
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); }
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()); }
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]); }
// 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); }
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()); }
private IEnumerable <Registration> GetDecorateeFactoryDependencies(KnownRelationship[] relationships) => from relationship in relationships where DecoratorHelpers.IsScopelessDecorateeFactoryDependencyType( relationship.Dependency.ServiceType, this.e.RegisteredServiceType) select relationship.Dependency.Registration;
private bool DecoratorNeedsADecorateeFactory() => ( from parameter in this.decoratorConstructor.GetParameters() where DecoratorHelpers.IsScopelessDecorateeFactoryDependencyType(parameter.ParameterType, this.registeredServiceType) select parameter) .Any();