/// <summary>
        /// Gets the required cast statement, if any, to use the value of a property when constructing the model.
        /// </summary>
        /// <param name="modelType">The model type.</param>
        /// <param name="propertyOfConcern">The property of concern.</param>
        /// <returns>
        /// The cast statement, if any is required.
        /// </returns>
        public static string CastIfConstructorParameterIsOfDifferentType(
            this ModelType modelType,
            PropertyOfConcern propertyOfConcern)
        {
            string result;

            var propertyName = propertyOfConcern.Name;

            if (modelType.PropertyNameToConstructorParameterTypeMap.ContainsKey(propertyName))
            {
                var constructorParameterType = modelType.PropertyNameToConstructorParameterTypeMap[propertyName];

                var propertyType = propertyOfConcern.PropertyType;

                result = propertyType != constructorParameterType
                    ? Invariant($"({constructorParameterType.ToStringReadable()})")
                    : string.Empty;
            }
            else
            {
                result = string.Empty;
            }

            return(result);
        }
Beispiel #2
0
        private static string GenerateHashCodeMethodCodeForProperty(
            this PropertyOfConcern propertyOfConcern)
        {
            new { propertyOfConcern }.AsArg().Must().NotBeNull();

            var result = Invariant($"Hash(this.{propertyOfConcern.Name})");

            return(result);
        }
        private static string GenerateEqualityLogicCodeForProperty(
            this PropertyOfConcern propertyOfConcern)
        {
            new { propertyOfConcern }.AsArg().Must().NotBeNull();

            var result = (propertyOfConcern.PropertyType == typeof(string))
                ? Invariant($"this.{propertyOfConcern.Name}.IsEqualTo(other.{propertyOfConcern.Name}, StringComparer.Ordinal)")
                : Invariant($"this.{propertyOfConcern.Name}.IsEqualTo(other.{propertyOfConcern.Name})");

            return(result);
        }
        /// <summary>
        /// Determines if the model's constructor is missing a parameter that corresponds
        /// to the specified property of concern.
        /// </summary>
        /// <remarks>
        /// This occurs when a base class property isn't a constructor parameter (so the concrete class is passing a compile-time constant to the base class).
        /// </remarks>
        /// <param name="modelType">The model type.</param>
        /// <param name="propertyOfConcern">The property of concern.</param>
        /// <returns>
        /// true if the model has a public, non-default constructor that is missing a parameter that corresponds to the specified property.
        /// </returns>
        public static bool IsMissingCorrespondingConstructorParameter(
            this ModelType modelType,
            PropertyOfConcern propertyOfConcern)
        {
            new { modelType }.AsArg().Must().NotBeNull();
            new { propertyOfConcern }.AsArg().Must().NotBeNull();

            var result = (modelType.HierarchyKind == HierarchyKind.ConcreteInherited) &&
                         (!modelType.Constructor.IsDefaultConstructor()) &&
                         (!modelType.Constructor.GetParameters().Select(_ => _.Name).Contains(propertyOfConcern.Name, StringComparer.OrdinalIgnoreCase));

            return(result);
        }
        /// <summary>
        /// Converts a property to it's corresponding parameter name
        /// in constructors and other methods.
        /// </summary>
        /// <param name="propertyOfConcern">The property of concern.</param>
        /// <param name="forXmlDoc">A value indicating whether the parameter name will be used used in XML doc.</param>
        /// <returns>
        /// The parameter name.
        /// </returns>
        public static string ToParameterName(
            this PropertyOfConcern propertyOfConcern,
            bool forXmlDoc = false)
        {
            new { propertyOfConcern }.AsArg().Must().NotBeNull();

            var result = propertyOfConcern.Name.ToLowerFirstCharacter(CultureInfo.InvariantCulture);

            if (!forXmlDoc)
            {
                using (var codeProvider = new CSharpCodeProvider())
                {
                    if (!codeProvider.IsValidIdentifier(result))
                    {
                        result = "@" + result;
                    }
                }
            }

            return(result);
        }
Beispiel #6
0
        private static string GenerateToStringForProperty(
            this PropertyOfConcern propertyOfConcern,
            bool useSystemUnderTest)
        {
            var name = propertyOfConcern.Name;
            var type = propertyOfConcern.PropertyType;

            var takesFormatProviderType = type;

            // an open nullable type will just result in the generic parameter as it's underlying type,
            // which is why we purposefully only check for closed nullable types here.
            if (type.IsClosedNullableType())
            {
                takesFormatProviderType = Nullable.GetUnderlyingType(type);
            }

            // ReSharper disable once PossibleNullReferenceException
            var takesFormatProvider = takesFormatProviderType.GetMethods().Where(_ => _.Name == "ToString").Where(_ => !_.IsObsolete()).Where(_ => _.GetParameters().Length == 1).Any(_ => typeof(IFormatProvider).IsAssignableFrom(_.GetParameters().Single().ParameterType));

            var result = name + " = {" + (useSystemUnderTest ? "systemUnderTest" : "this") + "." + name + (type.IsTypeAssignableToNull() ? "?" : string.Empty) + ".ToString(" + (takesFormatProvider ? "CultureInfo.InvariantCulture" : string.Empty) + ") ?? \"<null>\"}";

            return(result);
        }