Beispiel #1
0
            public static InterceptorAggregator <TInterceptor> GetAggregator(IInterceptors interceptors)
            {
                System.Diagnostics.Debug.Assert(interceptors != null);

                if (AggregatorGetter is null)
                {
                    SetAggregatorGetter(interceptors);
                }

                System.Diagnostics.Debug.Assert(AggregatorGetter != null);

                return(AggregatorGetter(interceptors));
Beispiel #2
0
 /// <summary>
 ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
 ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
 ///     any release. You should only use it directly in your code with extreme caution and knowing that
 ///     doing so can result in application failures when updating to a new Entity Framework Core release.
 /// </summary>
 public DiagnosticsLogger(
     [NotNull] ILoggerFactory loggerFactory,
     [NotNull] ILoggingOptions loggingOptions,
     [NotNull] DiagnosticSource diagnosticSource,
     [NotNull] LoggingDefinitions loggingDefinitions,
     [CanBeNull] IInterceptors interceptors = null)
 {
     DiagnosticSource = diagnosticSource;
     Definitions      = loggingDefinitions;
     Logger           = loggerFactory.CreateLogger(new TLoggerCategory());
     Options          = loggingOptions;
     Interceptors     = interceptors;
 }
Beispiel #3
0
        /// <summary>
        /// From the <see cref="IInterceptors"/> object, returns the aggregator of interceptors of the given type.
        /// </summary>
        private InterceptorAggregator <TInterceptor> GetAggregator(IInterceptors interceptors)
        {
            var aggregator = ReflectionCache.GetAggregator(interceptors);

            return(aggregator);
        }
Beispiel #4
0
                // Local function that creates and assigns the compiled getter
                static void SetAggregatorGetter(IInterceptors theInterceptors)
                {
                    lock (Lock)
                    {
                        if (AggregatorGetter != null)
                        {
                            return;
                        }

                        try
                        {
                            // Check everything with slow reflection once

                            var aggregatorsField = theInterceptors.GetType().GetField("_aggregators", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) ??
                                                   throw new Exception($"Field {theInterceptors.GetType().Name}._aggregators does not exist.");
                            if (!typeof(IReadOnlyDictionary <Type, IInterceptorAggregator>).IsAssignableFrom(aggregatorsField.FieldType))
                            {
                                throw new Exception($"Field {theInterceptors.GetType().Name}._aggregators is of unexpected type {aggregatorsField.FieldType.Name}.");
                            }

                            var aggregators = (IReadOnlyDictionary <Type, IInterceptorAggregator>?)aggregatorsField.GetValue(theInterceptors) ??
                                              throw new Exception($"Field {theInterceptors.GetType().Name}._aggregators contains a null value.");

                            if (!aggregators.TryGetValue(typeof(TInterceptor), out var aggregator))
                            {
                                throw new Exception($"Field {theInterceptors.GetType().Name}._aggregators did not contain an aggregator for {typeof(TInterceptor).Name}.");
                            }

                            if (aggregator is null)
                            {
                                throw new Exception($"Field {theInterceptors.GetType().Name}._aggregators contained a null aggregator for {typeof(TInterceptor).Name}.");
                            }

                            if (aggregator is not InterceptorAggregator <TInterceptor> typedAggregator)
                            {
                                throw new Exception($"Field {theInterceptors.GetType().Name}._aggregators contained an aggregator for {typeof(TInterceptor).Name} of unexpected type {aggregator.GetType().Name}.");
                            }

                            // Compile a fast expression tree
                            // Omit the checks, trusting that things will be the same in the future
                            {
                                var indexerMethod = typeof(IReadOnlyDictionary <Type, IInterceptorAggregator>).GetMethod("get_Item") ??
                                                    throw new Exception($"Type {typeof(IReadOnlyDictionary<Type, IInterceptorAggregator>).Name} does not have a single public indexer.");

                                // IInterceptors interceptors;
                                var param = Expression.Parameter(typeof(IInterceptors), "interceptors");
                                // (Interceptors)interceptors;
                                var convertedParam = Expression.Convert(param, theInterceptors.GetType());
                                // ((Interceptors)interceptors)._aggregators;
                                var aggregatorDictionary = Expression.Field(convertedParam, aggregatorsField);
                                var interceptorType      = Expression.Constant(typeof(TInterceptor));
                                // _aggregators[typeof(TInterceptor)]
                                var interceptionAggregator = Expression.Call(aggregatorDictionary, indexerMethod, interceptorType);
                                // (InterceptorAggregator<TInterceptor>)_aggregators[typeof(TInterceptor)]
                                var convertedInterceptionAggregator = Expression.Convert(interceptionAggregator, typeof(InterceptorAggregator <TInterceptor>));

                                var lambda = Expression.Lambda <Func <IInterceptors, InterceptorAggregator <TInterceptor> > >(convertedInterceptionAggregator, param);
                                AggregatorGetter = lambda.Compile();
                            }
                        }
                        catch (Exception e)
                        {
                            throw ThrowHelper.ThrowIncompatibleWithEfVersion(e);
                        }
                    }
                }