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); }
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); }
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.")); }
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); } }
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); } }
public void Should_not_detect_methods_where_there_are_none() { ParseMethodFinder.FindParseMethod(GetType()).Should().BeNull(); ParseMethodFinder.FindTryParseMethod(GetType()).Should().BeNull(); }
public void Should_detect_tryparse_method() { ParseMethodFinder.FindTryParseMethod(typeof(int)).Should().NotBeNull(); ParseMethodFinder.FindTryParseMethod(typeof(Guid)).Should().NotBeNull(); ParseMethodFinder.FindTryParseMethod(typeof(IPAddress)).Should().NotBeNull(); }
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); },