diff --git a/ProductivityTools.DescriptionValue.Tests/DescriptionAttributeExtensionsTests.cs b/ProductivityTools.DescriptionValue.Tests/DescriptionAttributeExtensionsTests.cs new file mode 100644 index 0000000..92b0418 --- /dev/null +++ b/ProductivityTools.DescriptionValue.Tests/DescriptionAttributeExtensionsTests.cs @@ -0,0 +1,77 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Text; +using System.ComponentModel; +using ProductivityTools.DescriptionValue; +using FluentAssertions; + +namespace ProductivityTools.DescriptionValue.Tests +{ + + [TestClass] + public class DescriptionAttributeExtensionsTests + { + + public class TestClass + { + [System.ComponentModel.Description("Property1 Description")] + public string Property1 { get; set; } + + public int Property2 { get; set; } + } + + [TestMethod] + public void GetPropertyDescription_ShouldReturnDescription_WhenDescriptionAttributeExists() + { + // Arrange + var myClass = new TestClass(); + + // Act + string description = myClass.GetPropertyDescription(x => x.Property1); + + // Assert + description.Should().Be("Property1 Description"); + } + + [TestMethod] + public void GetPropertyDescription_ShouldReturnEmptyString_WhenDescriptionAttributeDoesNotExist() + { + // Arrange + var myClass = new TestClass(); + + // Act + string description = myClass.GetPropertyDescription(x => x.Property2); + + // Assert + description.Should().BeEmpty(); + } + + [TestMethod] + public void DescriptionExists_ShouldReturnTrue_WhenDescriptionAttributeExists() + { + // Arrange + var myClass = new TestClass(); + + // Act + bool exists = myClass.PropertyDescriptionExists(x => x.Property1); + + // Assert + exists.Should().BeTrue(); + } + + [TestMethod] + public void DescriptionExists_ShouldReturnFalse_WhenDescriptionAttributeDoesNotExist() + { + // Arrange + var myClass = new TestClass(); + + // Act + bool exists = myClass.PropertyDescriptionExists(x => x.Property2); + + // Assert + exists.Should().BeFalse(); + } + } +} diff --git a/ProductivityTools.DescriptionValue.Tests/ProductivityTools.DescriptionValue.Tests.csproj b/ProductivityTools.DescriptionValue.Tests/ProductivityTools.DescriptionValue.Tests.csproj index 1e289e6..491a368 100644 --- a/ProductivityTools.DescriptionValue.Tests/ProductivityTools.DescriptionValue.Tests.csproj +++ b/ProductivityTools.DescriptionValue.Tests/ProductivityTools.DescriptionValue.Tests.csproj @@ -7,6 +7,7 @@ + diff --git a/ProductivityTools.DescriptionValue/DescriptionAttributeExtensions.cs b/ProductivityTools.DescriptionValue/DescriptionAttributeExtensions.cs new file mode 100644 index 0000000..b9b263b --- /dev/null +++ b/ProductivityTools.DescriptionValue/DescriptionAttributeExtensions.cs @@ -0,0 +1,86 @@ +using System; +using System.ComponentModel; +using System.Linq.Expressions; +using System.Reflection; + +namespace ProductivityTools.DescriptionValue +{ + public static class DescriptionAttributeExtensions + { + + /// + /// Gets the description specified by the DescriptionAttribute of a property. + /// + /// The type containing the property. + /// The type of the property for which to retrieve the description. + /// The instance of the containing class. + /// An expression that identifies the property for which to retrieve the description. + /// + /// The description specified by the DescriptionAttribute of the property, + /// or string.Empty if the attribute is not found or does not have a Description property. + /// + public static string GetPropertyDescription(this TObject obj, Expression> propertyExpression) where TObject : class + { + if (propertyExpression == null) + { + throw new ArgumentNullException(nameof(propertyExpression)); + } + + PropertyInfo propertyInfo = GetPropertyInfoFromExpression(propertyExpression); + + DescriptionAttribute descriptionAttribute = GetDescriptionAttribute(propertyInfo); + + return descriptionAttribute != null ? descriptionAttribute.Description : string.Empty; + } + + /// + /// Checks if a DescriptionAttribute exists for a property. + /// + /// The type containing the property. + /// The type of the property for which to check the DescriptionAttribute. + /// The instance of the containing class. + /// An expression that identifies the property for which to check the DescriptionAttribute. + /// + /// True if the DescriptionAttribute exists for the property; otherwise, false. + /// + public static bool PropertyDescriptionExists(this TObject obj, Expression> propertyExpression) where TObject : class + { + if (propertyExpression == null) + { + throw new ArgumentNullException(nameof(propertyExpression)); + } + + PropertyInfo propertyInfo = GetPropertyInfoFromExpression(propertyExpression); + + return GetDescriptionAttribute(propertyInfo) != null; + } + + private static PropertyInfo GetPropertyInfoFromExpression(Expression> expression) + { + MemberExpression memberExpression = GetMemberExpression(expression) ?? throw new ArgumentException("Property expression must be a MemberExpression.", nameof(expression)); + + PropertyInfo propertyInfo = memberExpression.Member as PropertyInfo ?? throw new ArgumentException("Property expression must represent a property.", nameof(expression)); + + return propertyInfo; + } + + private static MemberExpression GetMemberExpression(Expression> expression) + { + if (expression.Body is MemberExpression memberExpression) + { + return memberExpression; + } + + if (expression.Body is UnaryExpression unaryExpression && unaryExpression.Operand is MemberExpression operandExpression) + { + return operandExpression; + } + + return null; + } + + private static DescriptionAttribute GetDescriptionAttribute(PropertyInfo propertyInfo) => propertyInfo?.GetCustomAttribute(); + + } + +} diff --git a/ProductivityTools.DescriptionValue/ProductivityTools.DescriptionValue.csproj b/ProductivityTools.DescriptionValue/ProductivityTools.DescriptionValue.csproj index 6db3e01..aeb7eac 100644 --- a/ProductivityTools.DescriptionValue/ProductivityTools.DescriptionValue.csproj +++ b/ProductivityTools.DescriptionValue/ProductivityTools.DescriptionValue.csproj @@ -23,4 +23,8 @@ + + + +