private static void ResolveScopedOverrideFilter(
            FilterContext filterContext,
            FilterScope scope,
            AutofacFilterCategory filterCategory,
            ILifetimeScope lifeTimeScope,
            HttpActionDescriptor descriptor)
        {
            var filters = filterContext.LifetimeScope.Resolve <IEnumerable <Meta <IOverrideFilter> > >();

            foreach (var filter in filters)
            {
                var metadata = filter.Metadata.TryGetValue(FilterMetadataKey, out var metadataAsObject)
                    ? metadataAsObject as FilterMetadata
                    : null;

                if (metadata != null)
                {
                    foreach (var filterRegistration in metadata.PredicateSet)
                    {
                        if (FilterMatchesAndNotAlreadyAdded(filterContext, scope, filterCategory, lifeTimeScope, filterRegistration, descriptor))
                        {
                            filterContext.Filters.Add(new FilterInfo(filter.Value, scope));
                            filterContext.AddedFilters[filterCategory].Add(filterRegistration);
                        }
                    }
                }
            }
        }
        private static bool MatchingFilterAlreadyAdded(FilterContext filterContext, AutofacFilterCategory filterCategory, ILifetimeScope lifeTimeScope, HttpActionDescriptor descriptor, FilterPredicateMetadata metadata)
        {
            var filters = filterContext.AddedFilters[filterCategory];

            return(filters.Any(filter => filter.Scope == metadata.Scope &&
                               filter.Predicate(lifeTimeScope, descriptor)));
        }
        private static void ResolveScopedFilter <TFilter, TWrapper>(
            FilterContext filterContext,
            FilterScope scope,
            ILifetimeScope lifeTimeScope,
            HttpActionDescriptor descriptor,
            Func <HashSet <FilterMetadata>, TWrapper> wrapperFactory,
            AutofacFilterCategory filterCategory)
            where TFilter : class
            where TWrapper : class, IFilter
        {
            var filters = filterContext.LifetimeScope.Resolve <IEnumerable <Meta <Lazy <TFilter> > > >();

            // We'll store the unique filter registrations here until we create the wrapper.
            HashSet <FilterMetadata> metadataSet = null;

            foreach (var filter in filters)
            {
                var metadata = filter.Metadata.TryGetValue(FilterMetadataKey, out var metadataAsObject)
                    ? metadataAsObject as FilterMetadata
                    : null;

                // Match the filter category (action filter, authentication, the overrides, etc).
                if (metadata != null)
                {
                    // Each individual predicate of the filter 'could' match the action descriptor.
                    // The HashSet makes sure the same filter doesn't go in twice.
                    foreach (var filterRegistration in metadata.PredicateSet)
                    {
                        if (FilterMatches(scope, filterCategory, lifeTimeScope, descriptor, filterRegistration))
                        {
                            if (metadataSet == null)
                            {
                                // Don't define a hash set if something has already been registered (should just be the IOverrideFilters).
                                if (!MatchingFilterAlreadyAdded(filterContext, filterCategory, lifeTimeScope, descriptor, filterRegistration))
                                {
                                    metadataSet = new HashSet <FilterMetadata>
                                    {
                                        metadata,
                                    };

                                    filterContext.AddedFilters[filterCategory].Add(filterRegistration);
                                }
                            }
                            else
                            {
                                metadataSet.Add(metadata);
                            }
                        }
                    }
                }
            }

            if (metadataSet != null)
            {
                // Declare our wrapper (telling it which filters it is responsible for)
                var wrapper = wrapperFactory(metadataSet);
                filterContext.Filters.Add(new FilterInfo(wrapper, scope));
            }
        }
 private static bool FilterMatchesAndNotAlreadyAdded(
     FilterContext filterContext,
     FilterScope scope,
     AutofacFilterCategory filterCategory,
     ILifetimeScope lifeTimeScope,
     FilterPredicateMetadata metadata,
     HttpActionDescriptor descriptor)
 {
     return(FilterMatches(scope, filterCategory, lifeTimeScope, descriptor, metadata) &&
            !MatchingFilterAlreadyAdded(filterContext, filterCategory, lifeTimeScope, descriptor, metadata));
 }
 private static bool FilterMatches(
     FilterScope scope,
     AutofacFilterCategory filterCategory,
     ILifetimeScope lifeTimeScope,
     HttpActionDescriptor descriptor,
     FilterPredicateMetadata metadata)
 {
     return(metadata.FilterCategory == filterCategory &&
            metadata.Scope == scope &&
            metadata.Predicate(lifeTimeScope, descriptor));
 }