Add GetProperty that supports retrieval of interface properties. (#2255)

* Introduces a new static method `GetProperty` in the `Radzen.PropertyAccess` class to retrieve properties by name, including support for interfaces. Updates `DropDownBase.cs` to utilize this new method, enabling property retrieval for collections of interfaces in multiselect DropDowns.

* Add unit tests for property resolution in interfaces

Implemented unit tests in `PropertyAccessTests.cs` to verify
the resolution of `Description`, `Name`, and `Id` properties
from the interfaces `ISimpleInterface`, `ISimpleNestedInterface`,
and `ISimpleBaseInterface`. Defined the interfaces to support
the tests for the `GetProperty` method functionality.
This commit is contained in:
Petar Slavov
2025-08-15 09:28:52 +03:00
committed by GitHub
parent 3cc1f6b994
commit 4d9a9c9ac2
3 changed files with 68 additions and 2 deletions

View File

@@ -113,5 +113,43 @@ namespace Radzen.Blazor.Tests
{
public List<string> Values { get; set; }
}
[Fact]
public void GetProperty_Should_Resolve_DescriptionProperty()
{
var descriptionProperty = PropertyAccess.GetProperty(typeof(ISimpleInterface), nameof(ISimpleInterface.Description));
Assert.NotNull(descriptionProperty);
}
[Fact]
public void GetProperty_Should_Resolve_NameProperty()
{
var nameProperty = PropertyAccess.GetProperty(typeof(ISimpleInterface), nameof(ISimpleInterface.Name));
Assert.NotNull(nameProperty);
}
[Fact]
public void GetProperty_Should_Resolve_IdProperty()
{
var idProperty = PropertyAccess.GetProperty(typeof(ISimpleInterface), nameof(ISimpleBaseInterface.Id));
Assert.NotNull(idProperty);
}
interface ISimpleInterface : ISimpleNestedInterface
{
string Description { get; set; }
}
interface ISimpleNestedInterface : ISimpleBaseInterface
{
string Name { get; set; }
}
interface ISimpleBaseInterface
{
int Id { get; set; }
}
}
}

View File

@@ -3498,6 +3498,32 @@ namespace Radzen
return null;
}
/// <summary>
/// Gets the property by its name. If the type is an interface, it will search through all interfaces implemented by the type.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="property">The property.</param>
/// <returns>PropertyInfo.</returns>
public static PropertyInfo GetProperty(Type type, string property)
{
if (type.IsInterface)
{
var interfaces = type.GetInterfaces();
foreach (var @interface in interfaces)
{
var propertyInfo = @interface.GetProperty(property);
if (propertyInfo != null)
{
return propertyInfo;
}
}
}
return type.GetProperty(property);
}
/// <summary>
/// Gets the dynamic property expression when binding to IDictionary.
/// </summary>

View File

@@ -318,7 +318,8 @@ namespace Radzen
if (!string.IsNullOrEmpty(ValueProperty))
{
System.Reflection.PropertyInfo pi = PropertyAccess.GetElementType(Data.GetType()).GetProperty(ValueProperty);
var elementType = PropertyAccess.GetElementType(Data.GetType());
System.Reflection.PropertyInfo pi = PropertyAccess.GetProperty(elementType, ValueProperty);
internalValue = selectedItems.Select(i => GetItemOrValueFromProperty(i, ValueProperty)).AsQueryable().Cast(pi.PropertyType);
}
else
@@ -1167,7 +1168,8 @@ namespace Radzen
if (!string.IsNullOrEmpty(ValueProperty))
{
System.Reflection.PropertyInfo pi = PropertyAccess.GetElementType(Data.GetType()).GetProperty(ValueProperty);
var elementType = PropertyAccess.GetElementType(Data.GetType());
System.Reflection.PropertyInfo pi = PropertyAccess.GetProperty(elementType, ValueProperty);
internalValue = selectedItems.Select(i => GetItemOrValueFromProperty(i, ValueProperty)).AsQueryable().Cast(pi.PropertyType);
}
else