Пример #1
0
    public static void ProcessWritableProperties(this ObjectHandlerRequest command,
                                                 ICsharpExpressionDumperCallback callback,
                                                 IEnumerable <PropertyInfo> properties)
    {
        callback.ChainAppendLine()
        .ChainAppend(new string(' ', command.Level * 4))
        .ChainAppendLine("{");

        var level = command.Level + 1;

        foreach (var property in properties)
        {
            var propertyValue = property.GetValue(command.Instance);
            var propertyType  = propertyValue?.GetType();
            callback.Append(new string(' ', level * 4));
            var propertyCommand  = new CustomTypeHandlerRequest(propertyValue, propertyType, level);
            var propertyIsCustom = callback.IsPropertyCustom(propertyCommand, $"{property.Name} = ", ",");
            if (!propertyIsCustom)
            {
                callback.ChainAppend(property.Name)
                .ChainAppend(" = ")
                .ChainProcessRecursive(propertyValue, propertyValue?.GetType(), level)
                .ChainAppend(",");
            }

            callback.AppendLine();
        }

        level--;

        callback.ChainAppend(new string(' ', level * 4))
        .ChainAppend("}");
    }
    private static void AppendFinalize(ObjectHandlerRequest command,
                                       ICsharpExpressionDumperCallback callback,
                                       int level,
                                       bool first,
                                       PropertyInfo[] properties,
                                       List <string> processedProperties)
    {
        var writableProperties = properties.Where
                                 (
            property =>
            (command.IsAnonymousType || !property.IsReadOnly()) &&
            !processedProperties.Contains(property.Name) &&
            callback.IsPropertyValid(command, property)
                                 ).ToArray();

        if (!first)
        {
            callback.ChainAppend(new string(' ', level * 4))
            .ChainAppend(")");
        }
        else if (!command.IsAnonymousType && writableProperties.Length == 0)
        {
            callback.Append("()");
        }

        if (writableProperties.Length > 0)
        {
            command.ProcessWritableProperties(callback, writableProperties);
        }
    }
Пример #3
0
    public bool ProcessInstance(ObjectHandlerRequest command, ICsharpExpressionDumperCallback callback)
    {
        var type = command.Type ?? command.InstanceType;

        if (type == null)
        {
            return(false);
        }

        var level               = command.Level + 1;
        var first               = true;
        var properties          = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
        var processedProperties = new List <string>();

        foreach (var property in properties.Where(x => callback.IsPropertyValid(command, x)))
        {
            if (type.GetMethods().Any(x => x.Name == $"With{property.Name}"))
            {
                first = ProcessBuilderMethod(command, callback, level, first, processedProperties, property, "With");
            }
            else if (type.GetMethods().Any(x => x.Name == $"Add{property.Name}"))
            {
                first = ProcessBuilderMethod(command, callback, level, first, processedProperties, property, "Add");
            }
        }

        if (first)
        {
            // No 'With' or 'Add' methods found, let the default object handler handle this
            return(false);
        }

        return(true);
    }
    public bool ProcessInstance(ObjectHandlerRequest command, ICsharpExpressionDumperCallback callback)
    {
        if (command.Instance == null)
        {
            return(false);
        }

        var type = command.Type ?? command.InstanceType;

        if (type == null)
        {
            return(false);
        }

        var level               = command.Level + 1;
        var first               = true;
        var ctor                = callback.ResolveConstructor(type);
        var properties          = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
        var processedProperties = new List <string>();

        first = AppendReadOnlyProperties(command, callback, level, first, ctor, properties, processedProperties);

        level--;

        AppendFinalize(command, callback, level, first, properties, processedProperties);

        return(true);
    }
Пример #5
0
    private static bool ProcessBuilderMethod(ObjectHandlerRequest command,
                                             ICsharpExpressionDumperCallback callback,
                                             int level,
                                             bool first,
                                             List <string> processedProperties,
                                             PropertyInfo property,
                                             string methodPrefix)
    {
        if (first)
        {
            callback.Append("()");
            first = false;
        }
        var propertyValue = property.GetValue(command.Instance);

        var addedSomething = false;

        if (methodPrefix == "Add" &&
            !(propertyValue is string) &&
            propertyValue is IEnumerable enumerable)
        {
            var firstVal = true;
            level++;
            foreach (var value in enumerable.OfType <object>())
            {
                if (firstVal)
                {
                    firstVal       = false;
                    addedSomething = true;
                    callback.ChainAppendLine()
                    .ChainAppend(new string(' ', (level - 1) * 4))
                    .ChainAppend($".{methodPrefix}{property.Name}(")
                    .ChainAppendLine()
                    .ChainAppend(new string(' ', level * 4));
                }
                else
                {
                    callback.ChainAppend(",")
                    .ChainAppendLine()
                    .ChainAppend(new string(' ', level * 4));
                }
                callback.ProcessRecursive(value, value?.GetType(), level);
            }
        }
        else
        {
            addedSomething = true;
            callback.ChainAppendLine()
            .ChainAppend(new string(' ', level * 4))
            .ChainAppend($".{methodPrefix}{property.Name}(")
            .ChainProcessRecursive(propertyValue, propertyValue?.GetType(), level);
        }
        if (addedSomething)
        {
            callback.Append(")");
        }
        processedProperties.Add(property.Name);
        return(first);
    }
Пример #6
0
    public void ProcessInstance_Returns_True_When_PropertyValue_On_Immutable_Instance_Is_Null()
    {
        // Arrange
        var sut          = new DefaultObjectHandler();
        var instance     = new MyImmutableClass("test");
        var command      = new ObjectHandlerRequest(instance, typeof(MyImmutableClass), 0, typeof(MyImmutableClass), false);
        var callbackMock = new Mock <ICsharpExpressionDumperCallback>();

        // Act
        var actual = sut.ProcessInstance(command, callbackMock.Object);

        // Assert
        actual.Should().BeTrue();
    }
    public void ProcessInstance_Returns_False_On_Poco()
    {
        // Arrange
        var sut          = new BuilderObjectHandler();
        var instance     = new MyPocoClass();
        var command      = new ObjectHandlerRequest(instance, typeof(MyPocoClass), 0, typeof(MyPocoClass), false);
        var callbackMock = new Mock <ICsharpExpressionDumperCallback>();

        // Act
        var actual = sut.ProcessInstance(command, callbackMock.Object);

        // Assert
        actual.Should().BeFalse();
    }
    public void Can_Generate_Code_With_CustomObjectHandler()
    {
        // Arrange
        var sut          = new BuilderObjectHandler();
        var instance     = new MyBuilder().WithName("Test").AddValues("1", "2", "3");
        var command      = new ObjectHandlerRequest(instance, typeof(MyBuilder), 0, typeof(MyBuilder), false);
        var callbackMock = new Mock <ICsharpExpressionDumperCallback>();

        callbackMock.Setup(x => x.IsPropertyValid(It.IsAny <ObjectHandlerRequest>(), It.IsAny <PropertyInfo>())).Returns(true);

        // Act
        var actual = sut.ProcessInstance(command, callbackMock.Object);

        // Assert
        actual.Should().BeTrue();
    }
    public void ProcessInstance_Returns_False_On_Null_Type()
    {
        // Arrange
        var    sut          = new BuilderObjectHandler();
        object?instance     = null;
        var    command      = new ObjectHandlerRequest(instance, null, 0, null, false);
        var    callbackMock = new Mock <ICsharpExpressionDumperCallback>();

        callbackMock.Setup(x => x.IsPropertyValid(It.IsAny <ObjectHandlerRequest>(), It.IsAny <PropertyInfo>())).Returns(true);

        // Act
        var actual = sut.ProcessInstance(command, callbackMock.Object);

        // Assert
        actual.Should().BeFalse();
    }
    public bool IsValid(ObjectHandlerRequest command, PropertyInfo propertyInfo)
    {
        var defaultValue = propertyInfo.PropertyType.IsValueType && Nullable.GetUnderlyingType(propertyInfo.PropertyType) == null
            ? Activator.CreateInstance(propertyInfo.PropertyType)
            : null;

        var actualValue = propertyInfo.GetValue(command.Instance);

        if (defaultValue == null && actualValue == null)
        {
            return(false);
        }

        return(defaultValue == null ||
               actualValue == null ||
               !actualValue.Equals(defaultValue));
    }
    private static bool AppendReadOnlyProperties(ObjectHandlerRequest command,
                                                 ICsharpExpressionDumperCallback callback,
                                                 int level,
                                                 bool first,
                                                 ConstructorInfo?ctor,
                                                 PropertyInfo[] properties,
                                                 List <string> processedProperties)
    {
        if (!command.IsAnonymousType && ctor != null)
        {
            var arguments = ctor.GetParameters();
            if (arguments.Length > 0)
            {
                foreach (var argument in arguments)
                {
                    var readOnlyProperty = callback.ResolveReadOnlyProperty(properties, ctor, argument);
                    if (readOnlyProperty == null)
                    {
                        continue;
                    }

                    first = AppendInitialization(callback, level, first);

                    processedProperties.Add(readOnlyProperty.Name);

                    var value = readOnlyProperty.GetValue(command.Instance);

                    callback.ChainAppend(new string(' ', level * 4))
                    .ChainAppend(argument.Name)
                    .ChainAppend(": ")
                    .ChainProcessRecursive(value, value?.GetType(), level);
                }

                if (!first)
                {
                    callback.AppendLine();
                }
            }
        }

        return(first);
    }
    private void DoProcessRecursive(object?instance, Type?type, StringBuilder builder, int level)
    {
        var instanceType     = type ?? instance?.GetType();
        var instanceRequest  = new CustomTypeHandlerRequest(instance, instanceType, level);
        var instanceIsCustom = _customTypeHandlers.ProcessUntilSuccess(x => x.Process(instanceRequest, _instanceCallback));

        if (!instanceIsCustom && instanceType != null)
        {
            var isAnonymousType = instanceType.IsAnonymousType();
            _instanceCallback.Append("new ");

            if (!isAnonymousType)
            {
                _instanceCallback.AppendTypeName(instanceType);
            }

            var objectHandlerCommand = new ObjectHandlerRequest(instance, instanceType, level, type, isAnonymousType);
            var success = _objectHandlers.ProcessUntilSuccess(x => x.ProcessInstance(objectHandlerCommand, _instanceCallback));
            if (!success)
            {
                throw new InvalidOperationException($"There is no object handler which supports object of type [{instanceType?.FullName}]");
            }
        }
    }
 public bool IsPropertyValid(ObjectHandlerRequest command, PropertyInfo propertyInfo)
 => _objectHandlerPropertyFilters.All(x => x.IsValid(command, propertyInfo));