User not logged in - login - register
Home Calendar Books School Tool Photo Gallery Message Boards Users Statistics Advertise Site Info
go to bottom | |
 Message Boards » » Sanity check this for me (.NET) Page [1]  
FroshKiller
All American
51873 Posts
user info
edit post

I'm developing for an ASP.NET application. It targets the .NET 4.0 runtime. For reasons, we aren't using ASP.NET MVC. Here is a common use pattern:

1. Render a form with fields for selecting bits of data you're interested in.
2. The user makes selections on the form and posts it back to the server.
3. The application server maps the form selections to the conditions of a database query.
4. The record set returned by the query is bound to a table in the HTML response.

What I'm trying to do is move the application toward using classes that manage two key pieces: displaying an appropriate form and displaying an appropriate table. What I'd like to do is use attributes to mark specific members of a class as eligible for use in those contexts.

I know that inspecting attributes at runtime is icky. I don't care. We're using reflection all over the place, so who gives a shit? Literally no one will notice or care.

Here is an example I have in mind. Let's say I have a screen for looking up widgets. I want to define a Widget class that handles reading widget records from the database and all that jazz. A Widget's properties might include ProductType, ModelNumber, Price, IsSecretlyABomb, and IsDiscontinued.

ProductType and IsDiscontinued would be useful things to have on the form used to filter the lookup. Everything except IsSecretlyABomb is a good candidate to include in the tabular results.

I'd like to define attributes like maybe <Filterable("Multiple")> on the ProductType property, for example. Then, I could have one well designed and well implemented form manager sort of class that can take the Widget class, see which members are flagged with the appropriate attributes, and dynamically access those for form rendering so I'll never have to write any of this stupid boilerplate again.

I hesitate because it feels like I'm forgetting a better option. I can't really refactor any existing classes to make them conform to new interfaces or inherit from a different base class, but adding custom attributes for this seems like a slam dunk to me. Thoughts?

12/7/2015 1:55:37 PM

Novicane
All American
15408 Posts
user info
edit post

php that way ->>>

12/7/2015 6:33:25 PM

qntmfred
retired
40340 Posts
user info
edit post

if you can bind your forms to a dynamic you could do this

public static dynamic ToDynamic(this object value)
{
IDictionary expando = new ExpandoObject();

foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(value.GetType()))
{
if (property.Attributes.OfType<IsFilterableAttribute>().Any())
{
expando.Add(property.Name, property.GetValue(value));
}
}

return expando as ExpandoObject;
}


that'll return a type that just has the properties on it you care about.

12/8/2015 12:21:54 AM

moron
All American
33692 Posts
user info
edit post

Wouldn't you want this to be controllable by the user, rather than be in the code? Seems like this info should be in a database or config file somewhere, not part of a class...

12/8/2015 2:22:50 AM

FroshKiller
All American
51873 Posts
user info
edit post

qntmfred said:
Quote :
"if you can bind your forms to a dynamic you could do this"


You're just offering that up as a sample naive implementation of how to actually get the filterable properties once I've gone ahead with my idea, right? That looks useful.

moron said:
Quote :
"Wouldn't you want this to be controllable by the user, rather than be in the code? Seems like this info should be in a database or config file somewhere, not part of a class..."


Nah. That'd open me up to users making bad choices, thus diminishing the value of what they're seeing on screen. Users are like, "Show me everything!" Well, "everything" includes a load of misleading and confusing data, dude. Good specs mean you're seeing everything you need to see to make an informed decision and not one datum more.

Plus that would drastically increase the amount of code/scripts/whatever additional resources that'd need maintaining. If I get hit by a bus and the next guy wants to add some date property to the output, he has to remember, "Oh yeah, I have to add a new line to the PROPERTIES MANIFEST CONFIG FILE," etc.

I'm sure someone else will have the bright idea to add a GetFilterableProperties function or something that returns an array of property names or something like that. That's cute, but it would involve making broad changes with compile-time consequences. Yeah, adding attributes technically means those things as well, except we don't have the overhead of an additional function defined for every supported class. We're running in Object Explorer stealth mode here. The anatomies of the classes don't change with new attributes.

12/8/2015 6:38:46 AM

aaronburro
Sup, B
52655 Posts
user info
edit post

For the love of all that is holy, please don't use a fucking ExpandoObject. I'm saying this for the person who comes after you. Please. Don't do it.

12/11/2015 12:09:38 AM

FroshKiller
All American
51873 Posts
user info
edit post

Okay, but why not?

12/11/2015 7:52:36 AM

Wolfmarsh
What?
5975 Posts
user info
edit post

I'd like to know why too. ExpandoObjects are really useful in certain scenarios, like reading JSON or YAML that you don't have the corresponding class definition for.

12/11/2015 8:37:43 AM

aaronburro
Sup, B
52655 Posts
user info
edit post

Because it's not one of ^ scenarios. You have a strongly typed object already. It is an enormous pain to debug code with ExpandoObjects, almost as much as debugging DataTables. It's even harder to deduce what the hell is happening and when it is safe to add/remove properties with them. People just add stuff at random to them, and down the line you are faced with the nightmare of "what does this property actually do again?"

If this is a throwaway app, then do it. If it's not, then find a better solution. I'd go in the direction of creating the table and then dynamically removing columns based on the property attributes.

12/13/2015 7:05:33 PM

AntecK7
All American
7755 Posts
user info
edit post

Does the user really need that much customization for the table render? What type of interaction does the user need to perform with the table? Do you need to handle different selection options for different types of data, or enable different actions?

I.E. selecting a table item (row/cell???) choosing "Prepare Shipment" displaying an error if the item is "IsSecretlyABomb"

12/14/2015 4:27:14 PM

FroshKiller
All American
51873 Posts
user info
edit post

Don't get it twisted. This isn't for the user to use. This is to speed up development of all these stupid damn screens.

Imagine two classes that represent things that are so dissimilar that you can't come up with many useful abstractions, right? Like...I don't know, fucking MagicMarker and RapLyrics.

I get the requests to add new dashboards or something for looking at collections of these items. The MagicMarker spec tells me that they definitely want to see columns for Color and IsNonToxic and IsErasable. The RapLyrics wants to see Artist, NumberOfBars, and IsObscene.

I don't want to write a bunch of friggin' bespoke code for pulling those specific properties for instances of the classes in the collections. I just want to have one piece of code that inspects the class to find all the properties that are, like, dashboard-appropriate and does the needful. And ideally, I'm not actually changing the class definitions for all the classes I'm using on these dashboards aside from tagging the properties with the appropriate attribute(s).

[Edited on December 14, 2015 at 4:41 PM. Reason : ///]

12/14/2015 4:31:48 PM

 Message Boards » Tech Talk » Sanity check this for me (.NET) Page [1]  
go to top | |
Admin Options : move topic | lock topic

© 2024 by The Wolf Web - All Rights Reserved.
The material located at this site is not endorsed, sponsored or provided by or on behalf of North Carolina State University.
Powered by CrazyWeb v2.38 - our disclaimer.