コード例 #1
0
            private static Type DetermineImplementationType(ExpressionBuiltEventArgs e)
            {
                // singleton
                var constantExpression = e.Expression as ConstantExpression;

                if (constantExpression != null)
                {
                    return((constantExpression).Value.GetType());
                }

                // transient without initializers
                var newExpression = e.Expression as NewExpression;

                if (newExpression != null)
                {
                    return((newExpression).Constructor.DeclaringType);
                }

                // transient with initializers
                var invocation = e.Expression as InvocationExpression;

                if (invocation != null &&
                    invocation.Expression is ConstantExpression &&
                    invocation.Arguments.Count == 1 &&
                    invocation.Arguments[0] is NewExpression)
                {
                    return(((NewExpression)invocation.Arguments[0])
                           .Constructor.DeclaringType);
                }

                // implementation type can not be determined
                return(e.RegisteredServiceType);
            }
コード例 #2
0
        private void TryToApplyDecorator(ExpressionBuiltEventArgs e)
        {
            if (this.MustDecorate(e.RegisteredServiceType, out Type? closedDecoratorType))
            {
                var decoratorInterceptor =
                    new ServiceDecoratorExpressionInterceptor(this.data, this.registrationsCache, e);

                if (decoratorInterceptor.SatisfiesPredicate())
                {
                    if (this.data.DecoratorTypeFactory != null)
                    {
                        // Context gets set by SatisfiesPredicate
                        var context = decoratorInterceptor.Context !;

                        closedDecoratorType = this.GetDecoratorTypeFromDecoratorFactory(
                            e.RegisteredServiceType, context);
                    }

                    if (closedDecoratorType != null)
                    {
                        decoratorInterceptor.ApplyDecorator(closedDecoratorType);
                    }
                }
            }
        }
コード例 #3
0
            public void Decorate(object sender, ExpressionBuiltEventArgs e)
            {
                var serviceType = e.RegisteredServiceType;

                if (!serviceType.IsGenericType || serviceType.GetGenericTypeDefinition() != OpenGenericType ||
                    !Predicate(CreatePredicateContext(e)))
                {
                    return;
                }

                var closedGenericDecorator = OpenGenericDecorator
                                             .MakeGenericType(serviceType.GetGenericArguments());

                var ctor = closedGenericDecorator.GetConstructors().Single();

                var parameters =
                    from parameter in ctor.GetParameters()
                    let type = parameter.ParameterType
                               select type == serviceType
                        ? e.Expression
                        : Container.GetRegistration(type, true).BuildExpression();

                var expression = Expression.New(ctor, parameters);

                var info = GetServiceTypeInfo(e);

                info.AppliedDecorators.Add(closedGenericDecorator);

                e.Expression = expression;
            }
コード例 #4
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);
        }
コード例 #5
0
            private ServiceTypeDecoratorInfo GetServiceTypeInfo(
                ExpressionBuiltEventArgs e)
            {
                var containerCache = _serviceTypeInfos;

                if (containerCache == null)
                {
                    containerCache = new Dictionary <Container,
                                                     Dictionary <Type, ServiceTypeDecoratorInfo> >();
                    _serviceTypeInfos = containerCache;
                }

                if (!containerCache.ContainsKey(Container))
                {
                    containerCache[Container] =
                        new Dictionary <Type, ServiceTypeDecoratorInfo>();
                }

                var cache = containerCache[Container];

                if (!cache.ContainsKey(e.RegisteredServiceType))
                {
                    cache[e.RegisteredServiceType] =
                        new ServiceTypeDecoratorInfo(DetermineImplementationType(e));
                }

                return(cache[e.RegisteredServiceType]);
            }
コード例 #6
0
        private void ApplyDecoratorOnContainerUncontrolledCollection(
            ExpressionBuiltEventArgs e, Type?decoratorType)
        {
            var serviceType = e.RegisteredServiceType.GetGenericArguments()[0];

            var uncontrolledInterceptor = new ContainerUncontrolledServicesDecoratorInterceptor(
                this.data, this.singletonDecoratedCollectionsCache, e, serviceType);

            if (uncontrolledInterceptor.SatisfiesPredicate())
            {
                if (this.data.DecoratorTypeFactory != null)
                {
                    // Context gets set by SatisfiesPredicate
                    var context = uncontrolledInterceptor.Context !;

                    decoratorType = this.GetDecoratorTypeFromDecoratorFactory(
                        serviceType, context);
                }

                if (decoratorType != null)
                {
                    uncontrolledInterceptor.SetDecorator(decoratorType);
                    uncontrolledInterceptor.ApplyDecorator();
                }
            }
        }
 public void OnExpressionBuilt(object sender, ExpressionBuiltEventArgs e)
 {
     if (_predicate(e.RegisteredServiceType))
     {
         e.Expression = BuildProxyExpression(e);
     }
 }
 public ServiceDecoratorExpressionInterceptor(DecoratorExpressionInterceptorData data,
     Dictionary<InstanceProducer, Registration> registrations, ExpressionBuiltEventArgs e)
     : base(data)
 {
     this.registrations = registrations;
     this.e = e;
     this.registeredServiceType = e.RegisteredServiceType;
 }
コード例 #9
0
 public ServiceDecoratorExpressionInterceptor(DecoratorExpressionInterceptorData data,
                                              Dictionary <InstanceProducer, Registration> registrations, ExpressionBuiltEventArgs e)
     : base(data)
 {
     this.registrations         = registrations;
     this.e                     = e;
     this.registeredServiceType = e.RegisteredServiceType;
 }
コード例 #10
0
 public void OnExpressionBuilt(object sender, ExpressionBuiltEventArgs e)
 {
     if (this.Predicate(e.RegisteredServiceType))
     {
         ThrowIfServiceTypeNotAnInterface(e);
         e.Expression = this.BuildProxyExpression(e);
     }
 }
コード例 #11
0
 private static void ThrowIfServiceTypeNotInterface(ExpressionBuiltEventArgs e)
 {
     // NOTE: We can only handle interfaces, because
     // System.Runtime.Remoting.Proxies.RealProxy only supports interfaces.
     if (!e.RegisteredServiceType.IsInterface)
     {
         throw new NotSupportedException("Can't intercept type " + e.RegisteredServiceType.Name + " because it is not an interface.");
     }
 }
 public ContainerUncontrolledServicesDecoratorInterceptor(DecoratorExpressionInterceptorData data,
                                                          Dictionary <InstanceProducer, IEnumerable> singletonDecoratedCollectionsCache,
                                                          ExpressionBuiltEventArgs e, Type registeredServiceType)
     : base(data)
 {
     this.singletonDecoratedCollectionsCache = singletonDecoratedCollectionsCache;
     this.e = e;
     this.registeredServiceType = registeredServiceType;
 }
 public ContainerUncontrolledServicesDecoratorInterceptor(DecoratorExpressionInterceptorData data,
     Dictionary<InstanceProducer, IEnumerable> singletonDecoratedCollectionsCache,
     ExpressionBuiltEventArgs e, Type registeredServiceType)
     : base(data)
 {
     this.singletonDecoratedCollectionsCache = singletonDecoratedCollectionsCache;
     this.e = e;
     this.registeredServiceType = registeredServiceType;
 }
コード例 #14
0
            private SimpleDecoratorContext CreatePredicateContext(ExpressionBuiltEventArgs e)
            {
                var info = GetServiceTypeInfo(e);

                return(new SimpleDecoratorContext
                {
                    ServiceType = e.RegisteredServiceType,
                    Expression = e.Expression,
                    ImplementationType = info.ImplementationType,
                    AppliedDecorators = info.AppliedDecorators.ToArray()
                });
            }
コード例 #15
0
            public void OnExpressionBuilt(object sender, ExpressionBuiltEventArgs e)
            {
                if (!_predicate(e.RegisteredServiceType))
                {
                    return;
                }

                if (!e.RegisteredServiceType.IsInterface)
                {
                    // NOTE: We can only handle interfaces, because System.Runtime.Remoting.Proxies.RealProxy only supports interfaces.
                    throw new NotSupportedException($@"Can't intercept type {e.RegisteredServiceType.Name} because it is not an interface.");
                }
                e.Expression = BuildProxyExpression(e, _proxyGenerationOptions);
            }
        public ContainerControlledServicesDecoratorInterceptor(DecoratorExpressionInterceptorData data,
                                                               Dictionary <Type, IDecoratableEnumerable> decoratableEnumerablesCache,
                                                               ExpressionBuiltEventArgs e, Type registeredServiceType, Type decoratorType)
            : base(data)
        {
            this.decoratableEnumerablesCache = decoratableEnumerablesCache;
            this.e = e;
            this.registeredServiceType = registeredServiceType;

            this.decoratorConstructor = data.Container.Options.ConstructorResolutionBehavior
                                        .GetConstructor(this.registeredServiceType, decoratorType);

            // The actual decorator could be different. TODO: must... write... test... for... this.
            this.decoratorType = this.decoratorConstructor.DeclaringType;
        }
コード例 #17
0
        private void TryToApplyDecoratorOnContainerUncontrolledCollections(ExpressionBuiltEventArgs e)
        {
            if (!IsCollectionType(e.RegisteredServiceType) ||
                ControlledCollectionHelper.IsContainerControlledCollectionExpression(e.Expression))
            {
                // NOTE: Decorators on controlled collections will be applied by the normal mechanism.
                return;
            }

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

            if (this.MustDecorate(serviceType, out Type? decoratorType))
            {
                this.ApplyDecoratorOnContainerUncontrolledCollection(e, decoratorType);
            }
        }
            private Expression BuildProxyExpression(ExpressionBuiltEventArgs e)
            {
                var expr = _buildInterceptorExpression(e);

                var proxyType   = _getProxyType(e.RegisteredServiceType);
                var createProxy =
                    proxyType.GetTypeInfo().IsInterface ?
                    CreateInterfaceProxyWithTarget :
                    CreateClassProxyWithTarget;

                return(Expression.Convert(
                           Expression.Invoke(Expression.Constant(createProxy),
                                             Expression.Constant(proxyType, typeof(Type)),
                                             e.Expression,
                                             expr),
                           proxyType));
            }
コード例 #19
0
        private Expression BuildProxyExpression(ExpressionBuiltEventArgs e)
        {
            var expr = this.BuildInterceptorExpression(e);

            // Create call to
            // (ServiceType)Interceptor.CreateProxy(Type, IInterceptor, object)
            var proxyExpression =
                Expression.Convert(
                    Expression.Call(NonGenericInterceptorCreateProxyMethod,
                                    Expression.Constant(e.RegisteredServiceType, typeof(Type)),
                                    expr,
                                    e.Expression),
                    e.RegisteredServiceType);

            if (e.Expression is ConstantExpression && expr is ConstantExpression)
            {
                return(Expression.Constant(CreateInstance(proxyExpression), e.RegisteredServiceType));
            }

            return(proxyExpression);
        }
コード例 #20
0
        private void TryToApplyDecorator(ExpressionBuiltEventArgs e)
        {
            Type closedDecoratorType;

            if (this.MustDecorate(e.RegisteredServiceType, out closedDecoratorType))
            {
                var decoratorInterceptor =
                    new ServiceDecoratorExpressionInterceptor(this.data, this.registrationsCache, e);

                if (decoratorInterceptor.SatisfiesPredicate())
                {
                    if (this.data.DecoratorTypeFactory != null)
                    {
                        closedDecoratorType = this.GetDecoratorTypeFromDecoratorFactory(
                            e.RegisteredServiceType, decoratorInterceptor.Context);
                    }
                    
                    if (closedDecoratorType != null)
                    {
                        decoratorInterceptor.ApplyDecorator(closedDecoratorType);
                    }
                }
            }
        }
コード例 #21
0
 protected DecoratorPredicateContext CreatePredicateContext(ExpressionBuiltEventArgs e)
 {
     return(this.CreatePredicateContext(e.InstanceProducer, e.ReplacedRegistration,
                                        e.RegisteredServiceType, e.Expression));
 }
コード例 #22
0
 protected ServiceTypeDecoratorInfo GetServiceTypeInfo(ExpressionBuiltEventArgs e)
 {
     return(this.GetServiceTypeInfo(e.Expression, e.InstanceProducer, e.ReplacedRegistration,
                                    e.RegisteredServiceType));
 }
コード例 #23
0
 protected ServiceTypeDecoratorInfo GetServiceTypeInfo(ExpressionBuiltEventArgs e) =>
     this.GetServiceTypeInfo(e.Expression, e.InstanceProducer, e.ReplacedRegistration,
         e.RegisteredServiceType);
コード例 #24
0
        protected DecoratorPredicateContext CreatePredicateContext(ExpressionBuiltEventArgs e)
        {
            ServiceTypeDecoratorInfo info = this.GetServiceTypeInfo(e);

            return(this.CreatePredicateContext(e.RegisteredServiceType, e.Expression, info));
        }
コード例 #25
0
 public BuiltInfoInterceptor(ExpressionBuiltEventArgs buildInfo)
 {
     this.BuildInfo = buildInfo;
 }
コード例 #26
0
        internal void ExpressionBuilt(object sender, ExpressionBuiltEventArgs e)
        {
            this.TryToApplyDecorator(e);

            this.TryToApplyDecoratorOnContainerUncontrolledCollections(e);
        }
コード例 #27
0
 public BuiltInfoInterceptor(ExpressionBuiltEventArgs buildInfo)
 {
     this.BuildInfo = buildInfo;
 }
コード例 #28
0
 protected DecoratorPredicateContext CreatePredicateContext(ExpressionBuiltEventArgs e)
 {
     return this.CreatePredicateContext(e.InstanceProducer, e.ReplacedRegistration,
         e.RegisteredServiceType, e.Expression);
 }
コード例 #29
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);
            }
        }
コード例 #30
0
        internal void ExpressionBuilt(object sender, ExpressionBuiltEventArgs e)
        {
            this.TryToApplyDecorator(e);

            this.TryToApplyDecoratorOnContainerUncontrolledCollections(e);
        }
コード例 #31
0
        private void ApplyDecoratorOnContainerUncontrolledCollection(ExpressionBuiltEventArgs e,
            Type decoratorType)
        {
            var serviceType = e.RegisteredServiceType.GetGenericArguments()[0];

            var uncontrolledInterceptor = new ContainerUncontrolledServicesDecoratorInterceptor(this.data,
                this.singletonDecoratedCollectionsCache, e, serviceType);

            if (uncontrolledInterceptor.SatisfiesPredicate())
            {
                if (this.data.DecoratorTypeFactory != null)
                {
                    decoratorType = this.GetDecoratorTypeFromDecoratorFactory(
                        serviceType, uncontrolledInterceptor.Context);
                }

                if (decoratorType != null)
                {
                    uncontrolledInterceptor.SetDecorator(decoratorType);
                    uncontrolledInterceptor.ApplyDecorator();
                }
            }
        }