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); }
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); } } } }
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; }
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 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]); }
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; }
public ServiceDecoratorExpressionInterceptor(DecoratorExpressionInterceptorData data, Dictionary <InstanceProducer, Registration> registrations, ExpressionBuiltEventArgs e) : base(data) { this.registrations = registrations; this.e = e; this.registeredServiceType = e.RegisteredServiceType; }
public void OnExpressionBuilt(object sender, ExpressionBuiltEventArgs e) { if (this.Predicate(e.RegisteredServiceType)) { ThrowIfServiceTypeNotAnInterface(e); e.Expression = this.BuildProxyExpression(e); } }
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; }
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() }); }
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; }
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)); }
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); }
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); } } } }
protected DecoratorPredicateContext CreatePredicateContext(ExpressionBuiltEventArgs e) { return(this.CreatePredicateContext(e.InstanceProducer, e.ReplacedRegistration, e.RegisteredServiceType, e.Expression)); }
protected ServiceTypeDecoratorInfo GetServiceTypeInfo(ExpressionBuiltEventArgs e) { return(this.GetServiceTypeInfo(e.Expression, e.InstanceProducer, e.ReplacedRegistration, e.RegisteredServiceType)); }
protected ServiceTypeDecoratorInfo GetServiceTypeInfo(ExpressionBuiltEventArgs e) => this.GetServiceTypeInfo(e.Expression, e.InstanceProducer, e.ReplacedRegistration, e.RegisteredServiceType);
protected DecoratorPredicateContext CreatePredicateContext(ExpressionBuiltEventArgs e) { ServiceTypeDecoratorInfo info = this.GetServiceTypeInfo(e); return(this.CreatePredicateContext(e.RegisteredServiceType, e.Expression, info)); }
public BuiltInfoInterceptor(ExpressionBuiltEventArgs buildInfo) { this.BuildInfo = buildInfo; }
internal void ExpressionBuilt(object sender, ExpressionBuiltEventArgs e) { this.TryToApplyDecorator(e); this.TryToApplyDecoratorOnContainerUncontrolledCollections(e); }
protected DecoratorPredicateContext CreatePredicateContext(ExpressionBuiltEventArgs e) { return this.CreatePredicateContext(e.InstanceProducer, e.ReplacedRegistration, e.RegisteredServiceType, e.Expression); }
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); } }
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(); } } }