Ejemplo n.º 1
0
        /// <summary>
        /// Examines a <see cref="ConstructorInfo"/> instance
        /// and determines if it can be instantiated with the services embedded in
        /// the target <paramref name="container"/>.
        /// </summary>
        /// <param name="fuzzyItem">The <see cref="FuzzyItem{T}"/> that represents the constructor to be examined.</param>
        /// <param name="container">The container that contains the services that will be used to instantiate the target type.</param>
        /// <param name="maxIndex">Indicates the index that
        /// marks the point where the user-supplied arguments begin.</param>
        private static void CheckParameters(IFuzzyItem <TMethod> fuzzyItem,
                                            IServiceContainer container, int maxIndex)
        {
            var constructor  = fuzzyItem.Item;
            var currentIndex = 0;

            foreach (var param in constructor.GetParameters())
            {
                if (currentIndex == maxIndex)
                {
                    break;
                }

                var parameterType = param.ParameterType;
                var criteria      = new Criteria <TMethod> {
                    Type = CriteriaType.Critical, Weight = 1
                };

                // The type must either be an existing service
                // or a list of services that can be created from the container
                var predicate = parameterType.MustExistInContainer()
                                .Or(parameterType.ExistsAsServiceArray())
                                .Or(parameterType.ExistsAsEnumerableSetOfServices());

                criteria.Predicate = currentConstructor => predicate(container);
                fuzzyItem.Test(criteria);

                currentIndex++;
            }
        }
Ejemplo n.º 2
0
        private T GetNextBestMatch(IList <IFuzzyItem <T> > fuzzyList, List <Type> additionalArgumentTypes, T bestMatch)
        {
            int additionalArgumentCount = additionalArgumentTypes.Count;

            fuzzyList.Reset();

            // Match the number of arguments
            Func <T, bool> matchParameterCount = method =>
            {
                ParameterInfo[] parameters     = method.GetParameters();
                int             parameterCount = parameters != null
                                                                                 ? parameters.Length
                                                                                 : 0;

                return(parameterCount == additionalArgumentCount);
            };

            // Remove any methods that do not match
            // the parameter count
            fuzzyList.AddCriteria(matchParameterCount, CriteriaType.Critical);

            CheckArguments(fuzzyList, additionalArgumentTypes);
            IFuzzyItem <T> nextBestMatch = fuzzyList.BestMatch();

            if (nextBestMatch == null)
            {
                return(null);
            }

            return(nextBestMatch.Item);
        }
Ejemplo n.º 3
0
        public void ShouldReturnNullIfAllMatchScoresAreZero()
        {
            var fuzzyItem = new FuzzyItem <object>(new object());
            var fuzzyList = new List <IFuzzyItem <object> > {
                fuzzyItem
            };

            IFuzzyItem <object> bestMatch = fuzzyList.BestMatch();

            Assert.IsNull(bestMatch);
        }
Ejemplo n.º 4
0
        public void ShouldNotBeAbleToIgnoreFailedCriticalCriteria()
        {
            var fuzzyList = new List <IFuzzyItem <object> >();
            var fuzzyItem = new FuzzyItem <object>(new object());

            fuzzyList.Add(fuzzyItem);

            Mock <ICriteria <object> > trueCriteria   = GetMockCriteria(true, CriteriaType.Standard, 2);
            Mock <ICriteria <object> > failedCriteria = GetMockCriteria(false, CriteriaType.Critical, 1);

            // Boost the first item results so that the best match
            // should be biased towards the first item
            fuzzyItem.Test(trueCriteria.Object);

            // Make both items pass the first test
            var secondItem = new FuzzyItem <object>(new object());

            fuzzyList.Add(secondItem);

            fuzzyList.AddCriteria(trueCriteria.Object);

            // The first item should be the best match at this point
            IFuzzyItem <object> bestMatch = fuzzyList.BestMatch();

            Assert.AreSame(bestMatch, fuzzyItem);

            // Remove the second item from the list to avoid the
            // failed critical match
            fuzzyList.Remove(secondItem);

            // The failed critical criteria should eliminate
            // the first match as the best possible match
            fuzzyList.AddCriteria(failedCriteria.Object);

            // Reinsert the second value into the list
            // so that it can be chosen as the best match
            fuzzyList.Add(secondItem);

            // Run the test again
            bestMatch = fuzzyList.BestMatch();

            // The second item should be the best possible match,
            // and the first item should be ignored
            // because of the failed criteria
            Assert.AreSame(bestMatch, secondItem);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Returns the FuzzyItem with the highest confidence score in a given
        /// <see cref="IFuzzyItem{T}"/> list.
        /// </summary>
        /// <typeparam name="TItem">The type of item being compared.</typeparam>
        /// <param name="list">The fuzzy list that contains the list of possible matches.</param>
        /// <returns>The item with the highest match.</returns>
        public static IFuzzyItem <TItem> BestMatch <TItem>(this IList <IFuzzyItem <TItem> > list)
        {
            double             bestScore = 0;
            IFuzzyItem <TItem> bestMatch = null;

            foreach (var item in list)
            {
                if (item.Confidence <= bestScore)
                {
                    continue;
                }

                bestMatch = item;
                bestScore = item.Confidence;
            }

            return(bestMatch);
        }
Ejemplo n.º 6
0
        public void ShouldBeAbleToDetermineBestFuzzyMatch()
        {
            var mockFuzzyItem             = new Mock <IFuzzyItem <object> >();
            IFuzzyItem <object> fuzzyItem = mockFuzzyItem.Object;

            // This should be the best match
            mockFuzzyItem.Expect(f => f.Confidence).Returns(.8);

            var otherMockFuzzyItem            = new Mock <IFuzzyItem <object> >();
            IFuzzyItem <object> fauxFuzzyItem = otherMockFuzzyItem.Object;

            // This fuzzy item should be ignored since it has
            // a lower confidence rate
            otherMockFuzzyItem.Expect(f => f.Confidence).Returns(.1);

            var fuzzyList = new List <IFuzzyItem <object> > {
                fuzzyItem, fauxFuzzyItem
            };

            IFuzzyItem <object> bestMatch = fuzzyList.BestMatch();

            Assert.AreSame(bestMatch, fuzzyItem);
        }
Ejemplo n.º 7
0
        public void ShouldBeAbleToAddCriteriaToList()
        {
            // Return a predicate that always returns true
            var mockCriteria            = new Mock <ICriteria <object> >();
            ICriteria <object> criteria = mockCriteria.Object;

            var mockFuzzyItem             = new Mock <IFuzzyItem <object> >();
            IFuzzyItem <object> fuzzyItem = mockFuzzyItem.Object;

            // The Test method must be called on the fuzzy item
            mockFuzzyItem.Expect(fuzzy => fuzzy.Test(criteria));

            // Initialize the list of fuzzy items
            var fuzzyList = new List <IFuzzyItem <object> >();

            fuzzyList.Add(fuzzyItem);

            // Apply the criteria
            fuzzyList.AddCriteria(criteria);

            mockCriteria.VerifyAll();
            mockFuzzyItem.VerifyAll();
        }
        /// <summary>
        /// Returns the FuzzyItem with the highest confidence score in a given
        /// <see cref="IFuzzyItem{T}"/> list.
        /// </summary>
        /// <typeparam name="TItem">The type of item being compared.</typeparam>
        /// <param name="list">The fuzzy list that contains the list of possible matches.</param>
        /// <param name="tolerance">The tolerance level that determines the minimum percentage for a valid match (ranges between 0.0 and 1.0)</param>
        /// <returns>The item with the highest match.</returns>
        public static IFuzzyItem <TItem> BestMatch <TItem>(this IEnumerable <IFuzzyItem <TItem> > list, double tolerance)
        {
            if (tolerance < 0 || tolerance > 1)
            {
                throw new ArgumentOutOfRangeException("tolerance");
            }

            double             bestScore = 0;
            IFuzzyItem <TItem> bestMatch = null;

            foreach (var item in list)
            {
                if (item.Confidence <= bestScore || item.Confidence < tolerance)
                {
                    continue;
                }

                bestMatch = item;
                bestScore = item.Confidence;
            }

            return(bestMatch);
        }