コード例 #1
0
        public void Should_work_with_tryparse_method_provided_by_ParseMethodFinder()
        {
            var parser = new TryParseMethodParser(ParseMethodFinder.FindTryParseMethod(typeof(int)));

            parser.TryParse("12", out var value).Should().BeTrue();

            value.Should().Be(12);
        }
コード例 #2
0
        public SettingsBinderProvider()
        {
            containerWrapper = new Lazy <Container>(
                () =>
            {
                var container = new Container();

                foreach (var registration in customBinderRegistrationsBefore)
                {
                    registration(container);
                }

                container.RegisterConditional(
                    typeof(ISafeSettingsBinder <>),
                    typeof(NullableBinder <>),
                    c => c.ServiceType.GetGenericArguments()[0].IsNullable());
                container.RegisterConditional(
                    typeof(ISafeSettingsBinder <>),
                    typeof(EnumBinder <>),
                    c => c.ServiceType.GetGenericArguments()[0].IsEnum);
                container.RegisterConditional(
                    typeof(ISafeSettingsBinder <>),
                    typeof(ParseMethodBinder <>),
                    c => !c.Handled && ParseMethodFinder.HasAnyKindOfParseMethod(c.ServiceType.GetGenericArguments()[0]));
                container.Register(typeof(ISafeSettingsBinder <>), typeof(ListBinder <>));
                container.RegisterConditional(
                    typeof(ISafeSettingsBinder <>),
                    typeof(ReadOnlyListBinder <>),
                    c => !c.Handled);
                container.Register(typeof(ISafeSettingsBinder <>), typeof(DictionaryBinder <,>));
                container.Register(typeof(ISafeSettingsBinder <>), typeof(SetBinder <>));
                container.Register(typeof(ISafeSettingsBinder <ISettingsNode>), typeof(IdentityBinder));

                foreach (var registration in customBinderRegistrationsAfter)
                {
                    registration(container);
                }

                container.RegisterConditional(
                    typeof(ISafeSettingsBinder <>),
                    typeof(InterfaceBinder <>),
                    c => !c.Handled && c.ServiceType.GetGenericArguments()[0].IsInterface);
                container.RegisterConditional(
                    typeof(ISafeSettingsBinder <>),
                    typeof(ClassStructBinder <>),
                    c => !c.Handled);
                container.RegisterConditional(
                    typeof(ISettingsBinder <>),
                    typeof(UnsafeBinderWrapper <>),
                    c => !c.Handled);
                container.RegisterInstance(typeof(ISettingsBinderProvider), this);

                container.Verify();

                return(container);
            },
                LazyThreadSafetyMode.ExecutionAndPublication);
        }
コード例 #3
0
        public SettingsBindingResult <T> Bind(ISettingsNode rawSettings)
        {
            var tryParseMethod = ParseMethodFinder.FindTryParseMethod(typeof(T));

            if (tryParseMethod != null)
            {
                return(new PrimitiveBinder <T>(new TryParseMethodParser(tryParseMethod)).Bind(rawSettings));
            }

            var parseMethod = ParseMethodFinder.FindParseMethod(typeof(T));

            if (parseMethod != null)
            {
                return(new PrimitiveBinder <T>(new ParseMethodParser(parseMethod)).Bind(rawSettings));
            }

            return(SettingsBindingResult.Error <T>($"Failed to find a '{nameof(int.TryParse)}' or '{nameof(int.Parse)}' method on '{typeof(T)}' type."));
        }
コード例 #4
0
        private static IPrintToken CreateInternal([CanBeNull] object item, [NotNull] HashSet <object> path, [NotNull] PrintSettings settings)
        {
            if (item == null)
            {
                return(NullValue);
            }

            if (!path.Add(item))
            {
                return(CyclicValue);
            }

            try
            {
                var itemType = item.GetType();

                using (SecurityHelper.StartSecurityScope(itemType))
                {
                    var isSecretType = settings.HideSecretValues && SecurityHelper.IsSecret(itemType);

                    if (!isSecretType && CustomFormatters.TryFormat(item, out var customFormatting))
                    {
                        return(new ValueToken(customFormatting));
                    }

                    var isNode = typeof(ISettingsNode).IsAssignableFrom(itemType);
                    if (!isSecretType && (ParseMethodFinder.HasAnyKindOfParseMethod(itemType) || isNode) && ToStringDetector.TryInvokeCustomToString(itemType, item, out var asString))
                    {
                        return(new ValueToken(asString));
                    }

                    if (DictionaryInspector.IsSimpleDictionary(itemType))
                    {
                        var pairs  = DictionaryInspector.EnumerateSimpleDictionary(item);
                        var tokens = pairs
                                     .Select(pair => ConstructPropertyToken(isSecretType, () => CreateInternal(pair.Item2, path, settings), pair.Item1, settings))
                                     .ToArray();
                        if (tokens.Length == 0)
                        {
                            return(EmptyObjectValue);
                        }

                        return(new ObjectToken(tokens));
                    }

                    if (isSecretType)
                    {
                        return(SecretValue);
                    }

                    if (item is IEnumerable sequence)
                    {
                        if (!sequence.GetEnumerator().MoveNext())
                        {
                            return(EmptySequenceValue);
                        }

                        var tokens = new List <IPrintToken>();

                        foreach (var element in sequence)
                        {
                            tokens.Add(CreateInternal(element, path, settings));
                        }

                        return(new SequenceToken(tokens));
                    }

                    var fieldsAndProperties = new List <PropertyToken>();

                    foreach (var field in itemType.GetInstanceFields())
                    {
                        fieldsAndProperties.Add(ConstructProperty(field, () => CreateInternal(field.GetValue(item), path, settings), settings));
                    }

                    foreach (var property in itemType.GetInstanceProperties())
                    {
                        fieldsAndProperties.Add(ConstructProperty(property, () => CreateInternal(property.GetValue(item), path, settings), settings));
                    }

                    if (fieldsAndProperties.Count == 0)
                    {
                        return(EmptyObjectValue);
                    }

                    return(new ObjectToken(fieldsAndProperties));
                }
            }
            finally
            {
                path.Remove(item);
            }
        }
コード例 #5
0
        private static ISettingsNode ParseObject([CanBeNull] string name, [CanBeNull] object item, [NotNull] HashSet <object> path, [NotNull] ObjectSourceSettings settings)
        {
            if (item == null)
            {
                return(new ValueNode(name, null));
            }

            if (!path.Add(item))
            {
                throw new ArgumentException("Object has cyclic dependency.");
            }

            try
            {
                var itemType = item.GetType();

                if (CustomFormatters.TryFormat(item, out var customFormatting))
                {
                    return(new ValueNode(name, customFormatting));
                }

                if (ParseMethodFinder.HasAnyKindOfParseMethod(itemType) && ToStringDetector.TryInvokeCustomToString(itemType, item, out var asString))
                {
                    return(new ValueNode(name, asString));
                }

                if (DictionaryInspector.IsSimpleDictionary(itemType))
                {
                    return(ParseDictionary(name, DictionaryInspector.EnumerateSimpleDictionary(item), path, settings));
                }

                if (item is IEnumerable sequence)
                {
                    return(ParseEnumerable(name, sequence, path, settings));
                }

                var fieldsAndProperties = new List <ISettingsNode>();

                foreach (var field in itemType.GetInstanceFields())
                {
                    var fieldValue = field.GetValue(item);
                    if (fieldValue != null || !settings.IgnoreFieldsWithNullValue)
                    {
                        fieldsAndProperties.Add(ParseObject(field.Name, fieldValue, path, settings));
                    }
                }

                foreach (var property in itemType.GetInstanceProperties())
                {
                    var propertyValue = property.GetValue(item);
                    if (propertyValue != null || !settings.IgnoreFieldsWithNullValue)
                    {
                        fieldsAndProperties.Add(ParseObject(property.Name, propertyValue, path, settings));
                    }
                }

                return(new ObjectNode(name, fieldsAndProperties));
            }
            finally
            {
                path.Remove(item);
            }
        }
コード例 #6
0
        public void Should_not_detect_methods_where_there_are_none()
        {
            ParseMethodFinder.FindParseMethod(GetType()).Should().BeNull();

            ParseMethodFinder.FindTryParseMethod(GetType()).Should().BeNull();
        }
コード例 #7
0
 public void Should_detect_tryparse_method()
 {
     ParseMethodFinder.FindTryParseMethod(typeof(int)).Should().NotBeNull();
     ParseMethodFinder.FindTryParseMethod(typeof(Guid)).Should().NotBeNull();
     ParseMethodFinder.FindTryParseMethod(typeof(IPAddress)).Should().NotBeNull();
 }
コード例 #8
0
        public SettingsBinderProvider()
        {
            containerWrapper = new Lazy <Container>(
                () =>
            {
                var container = new Container();

                foreach (var registration in customBinderRegistrationsBefore)
                {
                    registration(container);
                }

                container.RegisterConditional(
                    typeof(ISettingsBinder <>),
                    c =>
                {
                    if (c.ServiceType.GetGenericArguments()[0].TryGetBindByAttribute(out var attr))
                    {
                        return(attr.BinderType);
                    }

                    throw new Exception("How could this happen? There is no doubt it's a bug in SimpleInjector implementation...");
                },
                    c => !c.Handled && c.ServiceType.GetGenericArguments()[0].TryGetBindByAttribute(out _));

                container.RegisterConditional(
                    typeof(ISafeSettingsBinder <>),
                    typeof(UninitializedClassStructBinder <>),
                    c => !c.Handled && UninitializedClassStructBinder <object> .CanBeUsedFor(c.ServiceType.GetGenericArguments()[0]));

                container.RegisterConditional(
                    typeof(ISafeSettingsBinder <>),
                    typeof(NullableBinder <>),
                    c => c.ServiceType.GetGenericArguments()[0].IsNullable());
                container.RegisterConditional(
                    typeof(ISafeSettingsBinder <>),
                    typeof(EnumBinder <>),
                    c => c.ServiceType.GetGenericArguments()[0].IsEnum);
                container.RegisterConditional(
                    typeof(ISafeSettingsBinder <>),
                    typeof(ParseMethodBinder <>),
                    c => !c.Handled && ParseMethodFinder.HasAnyKindOfParseMethod(c.ServiceType.GetGenericArguments()[0]));
                container.Register(typeof(ISafeSettingsBinder <>), typeof(ListBinder <>));
                container.RegisterConditional(
                    typeof(ISafeSettingsBinder <>),
                    typeof(ReadOnlyListBinder <>),
                    c => !c.Handled);
                container.Register(typeof(ISafeSettingsBinder <>), typeof(DictionaryBinder <,>));
                container.Register(typeof(ISafeSettingsBinder <>), typeof(SetBinder <>));
                container.Register(typeof(ISafeSettingsBinder <ISettingsNode>), typeof(IdentityBinder));

                var builtPredicates = customBinderRegistrationsPredicates.ToArray();

                container.RegisterConditional(
                    typeof(ISafeSettingsBinder <>),
                    typeof(SafeBinderWrapper <>),
                    c => !c.Handled &&
                    !(c.Consumer?.ImplementationType?.IsClosedTypeOf(typeof(UnsafeBinderWrapper <>)) ?? false) &&
                    (c.ServiceType.GetGenericArguments()[0].TryGetBindByAttribute(out _) ||
                     builtPredicates.Any(p => p(c))));

                container.RegisterConditional(
                    typeof(ISafeSettingsBinder <>),
                    typeof(InterfaceBinder <>),
                    c => !c.Handled && c.ServiceType.GetGenericArguments()[0].IsInterface);
                container.RegisterConditional(
                    typeof(ISafeSettingsBinder <>),
                    typeof(ConstructorBinder <>),
                    c => !c.Handled && ConstructorBinder <object> .CanBeUsedFor(c.ServiceType.GetGenericArguments()[0]));
                container.RegisterConditional(
                    typeof(ISafeSettingsBinder <>),
                    typeof(ClassStructBinder <>),
                    c => !c.Handled);
                container.RegisterConditional(
                    typeof(ISettingsBinder <>),
                    typeof(UnsafeBinderWrapper <>),
                    c => !c.Handled);
                container.RegisterInstance(typeof(ISettingsBinderProvider), this);

                container.Verify();

                return(container);
            },