Question

I want to create a GUI application (MVC asp web application) to create business rules that can be used for my business rules engine.

For this I have several objects (Request Objects) with various variables that can be used to create these rules. Because these request objects are also used in the validation of these rules.

An example, I have a TripRequest Object with a string variable 'Airline' and an int variable 'Price'.

I want in my GUI that when you select 'TripRequest' from a dropdown menu from various request objects. That a second dropdown menu is filled with all its fields (airline, price, etc).

Then when you select one of these fields, it needs to read its type (string, int) so that the GUI can give the appropriate operations (equals, not equals, larger, smaller than, etc) for the business rules.

My idea so far for creating such a GUI is to use reflection to read out all the field and method names from the various objects and use them to fill the GUI. Is this a good practice to use reflection?

I haven't used reflection before so I am wondering if there might be a better way to do it. I don't want to hard-code everything in because the application needs to be extend-able (new Request objects, new fields added to objects) without having to add more code to the GUI aswell.

my question: -Is reflection a good practice to use for this problem? -If not, what would you recommend using or looking at?

This is my first question on stackoverflow, if I did anything wrong please let me know so I can edit or change it.

Thank you for reading :).

Was it helpful?

Solution

You don't have to use reflection. Alternatives would include using some kind of external metadata to match up UI and data (and possibly generating code and UI from that metadata) or trying to statically analyse your code (perhaps using Roslyn!) to generate a suitable UI. However, reflection is likely to be far less painful. Potential downsides...

  • If you have deeply nested or complicated data structures you want to expose in the UI, it can be quite difficult to decide how best to do this.
  • If you don't have a clear set of 'UI-facing' objects with consistent rules for visibility, you'll have to spent time creating some kind of attribute or convention-based scheme to ensure you only expose the things you want to expose.
  • You may only find out at runtime (worst-case, in deployment) that you fail to correctly expose some rarely-used type.

Having said all that, if your data-types are generally just bags of properties, reflection is very straightforward. Here's some toy code that shows most of the relevant tricks you'll need, including setting up data-binding. Note that it is conventional to use properties rather than bare fields when reflecting over objects.

class Program
{
    [STAThread] 
    static void Main(string[] args)
    {
        var request = new TripRequest() {Airline = "Reflection Airways"};
        var window = new Window();
        var stackPanel = new StackPanel();
        window.Content = stackPanel;
        foreach (var property in request.GetType().GetProperties())
        {
            Console.WriteLine("Property named {0} has type {1}", property.Name, property.PropertyType);
            if (property.PropertyType == typeof(string))
            {
                var textBox = new TextBox();
                var binding = new Binding();
                binding.Source = request;
                binding.Path = new PropertyPath(property.Name);
                BindingOperations.SetBinding(textBox, TextBox.TextProperty, binding);
                stackPanel.Children.Add(textBox);
            }
            // etc for other types you care about
        }
        window.ShowDialog();
        Console.WriteLine("Airline is now {0}",request.Airline);
        Console.WriteLine("Finished");
    }
}

class TripRequest
{
    public string Airline { get; set; }
    public int Price { get; set; }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top