Made AdminPageProperty generic + added dynamic display property selecting
This commit is contained in:
@@ -38,10 +38,13 @@ internal class AdminContextGenerator : IAdminContextGenerator {
|
||||
foreach (var property in properties) {
|
||||
var propertyType = property.PropertyType.GenericTypeArguments[0];
|
||||
var pageGeneratorType = typeof(AdminPageGenerator<>).MakeGenericType(propertyType);
|
||||
var generatorInstance = Activator.CreateInstance(pageGeneratorType, [property.Name]); // Calls constructor with title attribute
|
||||
var generatorInstance = Activator.CreateInstance(pageGeneratorType);
|
||||
|
||||
var populatorMethod = pageGeneratorType.GetMethod(nameof(AdminPageGenerator<TContext>.ApplyConfigurationFromAttributes));
|
||||
populatorMethod?.Invoke(generatorInstance, [propertyType.GetCustomAttributes(false)]);
|
||||
var titleMethod = pageGeneratorType.GetMethod(nameof(AdminPageGenerator<TContext>.Title));
|
||||
titleMethod?.Invoke(generatorInstance, [property.Name]);
|
||||
|
||||
var populateMethod = pageGeneratorType.GetMethod(nameof(AdminPageGenerator<TContext>.ApplyConfigurationFromAttributes));
|
||||
populateMethod?.Invoke(generatorInstance, [propertyType.GetCustomAttributes(false)]);
|
||||
|
||||
_adminPages.Add(propertyType, generatorInstance);
|
||||
}
|
||||
|
||||
@@ -10,32 +10,34 @@ namespace HopFrame.Web.Admin.Generators.Implementation;
|
||||
internal sealed class AdminPageGenerator<TModel> : IAdminPageGenerator<TModel>, IGenerator<AdminPage<TModel>> {
|
||||
|
||||
public readonly AdminPage<TModel> Page;
|
||||
private readonly IDictionary<string, AdminPropertyGenerator> _propertyGenerators;
|
||||
private readonly Dictionary<string, object> _propertyGenerators;
|
||||
|
||||
public AdminPageGenerator() {
|
||||
Page = new AdminPage<TModel> {
|
||||
Permissions = new AdminPagePermissions(),
|
||||
ModelType = typeof(TModel)
|
||||
};
|
||||
_propertyGenerators = new Dictionary<string, AdminPropertyGenerator>();
|
||||
_propertyGenerators = new Dictionary<string, object>();
|
||||
|
||||
var type = typeof(TModel);
|
||||
var properties = type.GetProperties();
|
||||
var generatorType = typeof(AdminPropertyGenerator<>);
|
||||
|
||||
foreach (var property in properties) {
|
||||
var attributes = property.GetCustomAttributes(false);
|
||||
var genericType = generatorType.MakeGenericType(property.PropertyType);
|
||||
|
||||
var generator = Activator.CreateInstance(typeof(AdminPropertyGenerator), [property.Name, property.PropertyType]) as AdminPropertyGenerator;
|
||||
generator?.ApplyConfigurationFromAttributes(this, attributes, property);
|
||||
var generator = Activator.CreateInstance(genericType, [property.Name, property.PropertyType]);
|
||||
|
||||
var method = genericType
|
||||
.GetMethod(nameof(AdminPropertyGenerator<object>.ApplyConfigurationFromAttributes))?
|
||||
.MakeGenericMethod(type);
|
||||
method?.Invoke(generator, [this, attributes, property]);
|
||||
|
||||
_propertyGenerators.Add(property.Name, generator);
|
||||
}
|
||||
}
|
||||
|
||||
public AdminPageGenerator(string title) : this() {
|
||||
Title(title);
|
||||
}
|
||||
|
||||
public IAdminPageGenerator<TModel> Title(string title) {
|
||||
Page.Title = title;
|
||||
Page.Url ??= title.ToLower();
|
||||
@@ -100,13 +102,13 @@ internal sealed class AdminPageGenerator<TModel> : IAdminPageGenerator<TModel>,
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator Property<TProperty>(Expression<Func<TModel, TProperty>> propertyExpression) {
|
||||
public IAdminPropertyGenerator<TProperty> Property<TProperty>(Expression<Func<TModel, TProperty>> propertyExpression) {
|
||||
var property = GetPropertyInfo(propertyExpression);
|
||||
|
||||
if (_propertyGenerators.TryGetValue(property.Name, out var propertyGenerator))
|
||||
return propertyGenerator;
|
||||
return propertyGenerator as AdminPropertyGenerator<TProperty>;
|
||||
|
||||
var generator = Activator.CreateInstance(typeof(AdminPropertyGenerator), new { property.Name, property.PropertyType }) as AdminPropertyGenerator;
|
||||
var generator = Activator.CreateInstance(typeof(AdminPropertyGenerator<TProperty>), new { property.Name, property.PropertyType }) as AdminPropertyGenerator<TProperty>;
|
||||
generator?.ApplyConfigurationFromAttributes(this, property.GetCustomAttributes(false), property);
|
||||
_propertyGenerators.Add(property.Name, generator);
|
||||
|
||||
@@ -122,8 +124,10 @@ internal sealed class AdminPageGenerator<TModel> : IAdminPageGenerator<TModel>,
|
||||
public AdminPage<TModel> Compile() {
|
||||
var properties = new List<AdminPageProperty>();
|
||||
|
||||
foreach (var generator in _propertyGenerators.Values){
|
||||
properties.Add(generator.Compile());
|
||||
foreach (var generator in _propertyGenerators.Values) {
|
||||
var method = generator.GetType().GetMethod(nameof(AdminPropertyGenerator<object>.Compile));
|
||||
var prop = method?.Invoke(generator, []) as AdminPageProperty;
|
||||
properties.Add(prop);
|
||||
}
|
||||
|
||||
Page.Properties = properties;
|
||||
@@ -131,7 +135,7 @@ internal sealed class AdminPageGenerator<TModel> : IAdminPageGenerator<TModel>,
|
||||
return Page;
|
||||
}
|
||||
|
||||
private static PropertyInfo GetPropertyInfo<TSource, TProperty>(Expression<Func<TSource, TProperty>> propertyLambda) {
|
||||
public static PropertyInfo GetPropertyInfo<TSource, TProperty>(Expression<Func<TSource, TProperty>> propertyLambda) {
|
||||
if (propertyLambda.Body is not MemberExpression member) {
|
||||
throw new ArgumentException($"Expression '{propertyLambda}' refers to a method, not a property.");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using HopFrame.Web.Admin.Attributes;
|
||||
using HopFrame.Web.Admin.Attributes.Members;
|
||||
@@ -7,74 +8,86 @@ using HopFrame.Web.Admin.Models;
|
||||
|
||||
namespace HopFrame.Web.Admin.Generators.Implementation;
|
||||
|
||||
internal sealed class AdminPropertyGenerator(string name, Type type) : IAdminPropertyGenerator, IGenerator<AdminPageProperty> {
|
||||
internal sealed class AdminPropertyGenerator<TProperty>(string name, Type type) : IAdminPropertyGenerator<TProperty>, IGenerator<AdminPageProperty> {
|
||||
|
||||
private readonly AdminPageProperty _property = new() {
|
||||
Name = name,
|
||||
Type = type
|
||||
};
|
||||
|
||||
public IAdminPropertyGenerator Sortable(bool sortable) {
|
||||
public IAdminPropertyGenerator<TProperty> Sortable(bool sortable) {
|
||||
_property.Sortable = sortable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator Editable(bool editable) {
|
||||
public IAdminPropertyGenerator<TProperty> Editable(bool editable) {
|
||||
_property.Editable = editable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator DisplayValueWhileEditing(bool display) {
|
||||
public IAdminPropertyGenerator<TProperty> DisplayValueWhileEditing(bool display) {
|
||||
_property.EditDisplayValue = display;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator DisplayInListing(bool display = true) {
|
||||
public IAdminPropertyGenerator<TProperty> DisplayInListing(bool display = true) {
|
||||
_property.DisplayInListing = display;
|
||||
_property.Sortable = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator Ignore(bool ignore = false) {
|
||||
public IAdminPropertyGenerator<TProperty> Ignore(bool ignore = false) {
|
||||
_property.Ignore = ignore;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator Generated(bool generated = true) {
|
||||
public IAdminPropertyGenerator<TProperty> Generated(bool generated = true) {
|
||||
_property.Generated = generated;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator Bold(bool bold = true) {
|
||||
public IAdminPropertyGenerator<TProperty> Bold(bool bold = true) {
|
||||
_property.Bold = bold;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator DisplayName(string displayName) {
|
||||
public IAdminPropertyGenerator<TProperty> DisplayName(string displayName) {
|
||||
_property.DisplayName = displayName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator Description(string description) {
|
||||
public IAdminPropertyGenerator<TProperty> Description(string description) {
|
||||
_property.Description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator Prefix(string prefix) {
|
||||
public IAdminPropertyGenerator<TProperty> Prefix(string prefix) {
|
||||
_property.Prefix = prefix;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator Validator(Func<object, bool> validator) {
|
||||
public IAdminPropertyGenerator<TProperty> Validator(Func<object, bool> validator) {
|
||||
_property.Validator = validator;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator IsSelector<TSelector>() {
|
||||
public IAdminPropertyGenerator<TProperty> IsSelector<TSelector>() {
|
||||
_property.SelectorType = typeof(TSelector);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> DisplayProperty<TListingProperty>(Expression<Func<TProperty, TListingProperty>> propertyExpression) {
|
||||
var property = AdminPageGenerator<object>.GetPropertyInfo(propertyExpression);
|
||||
_property.DisplayPropertyName = property.Name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAdminPropertyGenerator<TProperty> DisplayPropertyForListType<TInnerProperty>(Expression<Func<TInnerProperty, object>> propertyExpression) {
|
||||
var property = AdminPageGenerator<object>.GetPropertyInfo(propertyExpression);
|
||||
_property.DisplayPropertyName = property.Name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AdminPageProperty Compile() {
|
||||
_property.DisplayName ??= _property.Name;
|
||||
return _property;
|
||||
@@ -129,5 +142,10 @@ internal sealed class AdminPropertyGenerator(string name, Type type) : IAdminPro
|
||||
var attribute = attributes.Single(a => a is AdminPrefixAttribute) as AdminPrefixAttribute;
|
||||
Prefix(attribute?.Prefix);
|
||||
}
|
||||
|
||||
if (attributes.Any(a => a is ListingPropertyAttribute)) {
|
||||
var attribute = attributes.Single(a => a is ListingPropertyAttribute) as ListingPropertyAttribute;
|
||||
_property.DisplayPropertyName = property.Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user