I am working on an application where a form will be created at runtime based on data from a database. It currently uses reflection to create the control and add it to the form.
With this I can easily dynamic create a form at runtime, but next I ran into the issue of how to access the currently selected, eg: TextBox.Text versus DropDownList.SelectedValue. To "fix" this, I created an interface with the method of GetValue. With this, I create a new class and inherit from the respective control and implement the interface.
Now I can easily iterate over the form controls to see if they implement the interface and then get the value of the control.
The question to all of this is: Is this the best way to accomplish this?
To note: I fully expect the controls available to build these forms to get to 15+.
Example of class:
public interface IFormField
{
string GetId();
object GetValue();
}
public TextBox : System.Web.UI.WebControls.TextBox, IFormField
{
public string GetId()
{
return ID;
}
public object GetValue()
{
return Text;
}
}
While I like interfaces, as noted with the "create a new class and inherit from the respective control" .. using new interfaces require that the underlying types are modified. This is not always practical for this case. So, while I won't claim that interfaces aren't appropriate here, I will provide alternative ideas.
This first approach uses a companion object which knows about the control, and how to get the value from the control. This class could use an interface but it is not required here. It allows delaying of the fetcher (in a well-typed manner) but also requires that it's explicit set per companion instance.
interface IWithValue {
string Value { get; }
}
class ControlCompanion<T>: IWithValue where T: Control {
IFunc<Control, string> readValue;
public T Control { get; private set; }
public string Value { get { return readValue(Control); } }
public ControlCompanion (T control, IFunc<T, string> readValue) {
Control = control;
this.readValue = readValue;
}
}
// this is typed narrowly here, but it could be typed wider to
// the actual ControlCompanion if needing additional information
// or actions wrt. the particular control
var valueAccessors = new List<IWithValue>();
var textBox = new TextBox();
valueAccessors.Add(new ControlCompanion(textBox, (c) => c.Text));
var comboBox = new ComboBox();
valueAccessors.Add(new ControlCompanion(comboBox, (c) => c.SelectedValue));
var allValues = valueAccessors.Select(v => v.Value);
Another alternative is to create a function that knows how to extract the values. Because these controls are "created dynamically" (e.g. of type Control) we can't use method overloading directly and must therefore accept the more general type and use some form of reflection or type refinement.
string GetValue(Control c) {
// using this form will allow invalid path detection
TextBox tb;
ComboBox cb;
if ((tb = c as TextBox) != null) {
return tb.Text;
} else if ((cb = c as ComboBox) != null) {
return GetValue(cb);
} else {
throw new Exception("Unsupported control");
}
}
// but we could use overloading once refined ..
string GetValue(ComboBox cb) {
return cb.SelectedValue;
}
Of course, the above two approaches could be combined1 - e.g. a GetValue function that use a per-type extractor (similar to ControlCompanion but independent of a control instance) looked up by a map/dictionary based on the actual type of the control object. If one didn't even want to maintain the map/dictionary manually, assembly reflection could load these per-type extractors automatically - oh, the possibilities and possible complexity!
Along the same lines but more general than the above suggestion is to use Type Converters which is quite a complete (if not complex) setup to handle converting types - even when those types cannot be modified or extended.
There are several different possibilities, and while extending controls and adding interfaces does usually work (it requires the controls can be registered as safe and created by the particular refined implementation), it is limited to cases in which said types can accommodate such changes.
1Okay, here is a rough idea for a general "switchless" GetValue. Note that it separates the control instance from the "fetcher". In fact, such an inversion could even be used to "get companions" to avoid explicit wrapping as in the first example.
interface IFetchValue {
string FetchValue(Control c);
}
abstract class Fetcher<T>: IFetchValue where T : Control {
abstract protected FetchControlValue(T c);
public string FetchValue (Control c) {
return FetchControlValue((T)c);
}
}
class TextBoxFetcher: Fetcher<TextBox> {
protected string FetchControlValue (TextBox tb) {
return tb.Value;
}
}
class ComboBoxFetcher: Fetcher<ComboBox> {
protected string FetchControlValue (ComboBox cb) {
return cb.SelectedValue;
}
}
// This could be initialized via reflection of all
// Fetcher<T>/IFetchValue types with a bit more work.
IDictionary<Type, IFetchValue> map = new Dictionary<Type, IFetchValue> {
{ typeof(TextBox), new TextBoxFetcher() },
{ typeof(ComboBox), new ComboBoxFetcher() },
};
string GetValue(Control c) {
IFetchValue fetcher;
// This should be smarter to also try parent types or
// check general assignability.
if (c != null && map.TryGetValue(c.GetType(), out fetcher)) {
return fetcher(c);
} else {
throw new Exception("Whoops!");
}
}
In addition, your favorite DI/IoC framework might support similar resolve capabilities which would then just push this maintenance into the configuration. Again - many ways, and many ways to make it complicated.
Pretty much. This is one of the main reasons why inheritance/polymorphism are useful. It allows calling code to deal with a generic collection which could actually have many deriving types and deal with them all as if they were the same thing.
If you only have a two or three types it might be simpler to skip this, but as the set of types you can operate on grows this rapidly becomes the best option. Also, I'd like to point out that I don't deal with WinForm types very much, there may already be some support for this type of behavior (which you'd be duplicating) that I don't know about.
You can do it this way (just to state the obvious...), but personally I wouldn't have. Extending a number of controls when all you are doing is adding a single method as part of an interface implementation is a reasonably long winded way to do it.
I would have used a helper method which takes a Control as its input, and checks the type of the control (via casting in lieu of a more language specific option) and then returns the control's value as an object.
The purpose of an interface is to establish a contract irrespective of the actual implementation, so you haven't used it incorrectly, you've just done more work than you really needed to.
Your approach is good and correct if it fullfils your needs and simplifies life.
I want to show an alternative way of control's value retrieval, the way of how it is accomplished in ASP.NET Web Forms itself. This approach could be useful if you don't want to bother with inheritance and if you are using standard input controls or all your controls are decorated with ValidationPropertyAttribute (which is mandatory if you want to use standard validation controls with your custom ones).
To retrieve value of any standard input control we need to use BaseValidator.GetValidationProperty method. This method returns PropertyDescriptor instance for validation property which holds control's value (except ListItem, but this case is covered in code snippet).
So the complete code for value retrieval would be:
public static string GetControlValue(Control c)
{
// This code is copied as-is from BaseValidator.GetControlValidationValue method
PropertyDescriptor prop = BaseValidator.GetValidationProperty(c);
if (prop == null) {
return null;
}
object value = prop.GetValue(c);
if (value is ListItem) {
return((ListItem) value).Value;
}
else if (value != null) {
return value.ToString();
}
else {
return string.Empty;
}
}
Related
I'm using an MVP pattern to expose field values from my View to my Presenter. I'd like to add an ErrorProvider to my View and add the errors from the Presenter, but that would mean exposing my controls, which I'm not keen on doing. My solution involved creating an ExposableControlValue class that exposes a value generically and has the added function CreateError(string errorMessage).
public interface IExposableControlValue<T>
{
T Value { get; set; }
void CreateError(string errorMessage);
void ClearErrors();
}
My thought was, I'll pass in the Property by reference and now my generic value will essentially point to the Control's backing field. All the ErrorProvider logic could be handled View side and all of the error checking could be handled by the presenter.
Obviously, I'm here because you can't pass the Property by reference, and all of the examples I've seen aren't close enough to my situation that I can decipher them for this example.
I'd also be fine with setting T Get() , Set(T value)methods dynamically if there is a way to do that, but in short, I'd like to mimic having that Property 'live' inside of my class instance.
I'll answer my own question as I finally was able to work this to my desired needs.
Using a factory pattern, I was able to make a new method CreateNew
public IExposableControlValue<T> CreateNew<T>(ErrorProvider errorProvider, Control control, Func<T> get, Action<T> set) {
var param1 = new ConstructorArgument("errorControl", errorProvider);
var param2 = new ConstructorArgument("control", control);
var exposableControlValue = resolutionRoot.Get<IExposableControlValue<T>>(param1, param2);
exposableControlValue.CreateSet(set);
exposableControlValue.CreateGet(get);
return exposableControlValue;
}
I'm using ninject, but the concept is the same. Essentially I'm asking the user for a few dependcies to create a new instance of this class. Then, when I want to actually expose the inner Generic value, I do it like so:
Func<T> get;
Action<T> set;
public ExposableControlValue(ErrorProvider errorControl, Control control) {
...configure my dependcies
}
public T Value { get { return get.Invoke(); } set { set.Invoke(value); } }
Finally, when I actually use the factory CreateNew method, I pass in some arguments depending on the property that I need
_forSomethingBackingField = exposableControlFactory.CreateNew<decimal>(errorProvider, numericUpDownForSomething,
() => { return numericUpDownForSomething.Value; }, (decimal d) => { numericUpDownForSomething.Value = d; });
The decimal is my generic value for the numeric up down. If you wanted to do this with a string, you would simply use string as the generic argument and pass (string s) = > someControlWithTextProperty.Text = s to the anonymous method param. Of course, doing so you would want to make sure that the Property that you are using is actually of the type you pass.
Good Day,
I have a situation where I'm using code that contains a class called ImportFileContext. The code looks like:
// One of 5 different types can be passed in
public AddImportData(CustomType ModelData)
{
// Depending on which 5 different types, the formatted type will change
FormattedType data = ConvertModelDataToFormattedData(ModelData);
using (var db = new ImportFileContext())
{
// Can this next line be made dynamic?
db.ImportFormattedData.Add(data);
db.SaveChanges();
}
}
Basically, a CustomType will always be passed in to the method. However, there are five different custom types that can be passed in. Depending on which 5 can be passed in, the data will be modified.
Use cases:
Custom Type passed in, format data to a specific format, then add that item to
List of the db instance.
Custom Type 2 passed in, format data to a specific format, then add that item to
List of the db instance.
Custom Type 3 passed in, format data to a specific format, then add that item to
List of the db instance.
So what I'm looking for is a way add an item to the List depending on the data type without having to write several different methods to test which type I'm receiving then adding the item. I know of the strategy pattern and I could use that, but what about adding an item to a list?
I'm really trying to avoid writing code that would look like:
// One of 5 different types can be passed in
public AddImportData(CustomType ModelData)
{
// Depending on which 5 different types, the formatted type will change
FormattedType data = ConvertModelDataToFormattedData(ModelData);
using (var db = new ImportFileContext())
{
if (typeof(ModelData) == "CustomType")
db.ImportFormattedData.Add(data);
elseif (typeof(ModelData) == "CustomType1")
db.ImportCsvData.Add(data);
elseif (typeof(ModelData) == "CustomType2")
db.ImportTabDelimetedData.Add(data);
db.SaveChanges();
}
}
TIA,
coson
I don't know how feasible this is for your application, but you can always add the specific behavior to the CustomType class and subclasses can implement it however they need to.
public class CustomType
{
public virtual void FormatAndWriteToDB(DataBase db);
}
And then sublasses override as needed
public class CustomType1 : CustomType
{
public override void FormatAndWriteToDB(DataBase db)
{
FormattedType data = ConvertModelDataToFormattedData(ModelData);
db.ImportCsvData.Add(data);
}
}
That would make your code very clean in the example method:
public AddImportData(CustomType ModelData)
{
ModelData.FormatAndWriteToDB(db);
db.SaveChanges();
}
Of course you can change this around a bit. For example, if the FormattedType call is common to all of them, you could leave that in the AddImportData method and pass it as an argument to the FormatAndWriteToDB method.
The advantage of this is future additions just require implementing the new subclass of CustomType and no modification is needed to AddImportData.
Sounds to me like you're looking for double-dispatch. You can do this with the Visitor Pattern--which is basically what David Mason detailed--where you decouple the algorithm from the data by putting logic (the visit) into the class that contains the data. That, of course works, but requires you to modify the class outside of the algorithm in order to visit.
I find this complex and it's really just there because statically typed object oriented languages don't normally do runtime overloading. Fortunately in C# 4 they introduced the dynamic keyword which allows use to implement double dispatch much easier--or at least in a way that looks more like method overloading. Which means you create the method overloads, assign the value to dynamic variable, then invoke the method. The method that gets call will be chosen at runtime based on the value. For example:
public static void AddImportData(CustomType ModelData)
{
FormattedType data = ConvertModelDataToFormattedData(ModelData);
using (var db = new ImportFileContext())
{
dynamic temp = ModelData;
ImportData(ModelData, data, db);
}
}
private static void ImportData(CustomType modelData, FormattedType data, ImportFileContext db)
{
db.ImportFormattedData.Add(data);
db.SaveChanges();
}
private static void ImportData(CustomType1 modelData, FormattedType data, ImportFileContext db)
{
db.ImportCsvData.Add(data);
db.SaveChanges();
}
private static void ImportData(CustomType1 modelData, FormattedType data, ImportFileContext db)
{
db.ImportTabDelimetedData.Add(data);
db.SaveChanges();
}
I have more details on my blog at: http://msmvps.com/blogs/peterritchie/archive/2010/05/24/using-the-dynamic-keyword-in-c-to-improve-object-orientation.aspx
I'm again in the position to figure a way out to handle lists with subsidiary objects on our business objects.
Actually, our code often looks like this:
public class Object
{
private List<SubsidiaryObject> subsidiaryObjects = null;
public List<SubsidiaryObject> SubsidiaryObjects
{
get
{
if (this.subsidiaryObjects == null)
{
this.subsidiaryObjects = DBClass.LoadListFromDatabase();
}
return this.subsidiaryObjects;
}
set
{
this.subsidiaryObjects = value;
}
}
}
The Con on this:
The property is referenced in presentation layer and used for DataBinding. Releasing the reference to the actual list and replacing it with a new one will end in an referenced list in the GUI that does not have anything left with the list on the object.
The Pro on this:
Easy way of reloading the list (just set the reference to null and then get it again).
I developed another class that uses the following pattern:
public class Object2
{
private readonly List<SubsidiaryObject> subsidiaryObjects = new List<SubsidiaryObject>();
public List<SubsidiaryObject> SubsidiaryObjects
{
get
{
return this.subsidiaryObjects;
}
}
public void ReloadSubsidiaryObjects()
{
this.SubsidiaryObjects.Clear();
this.SubsidiaryObjects.AddRange(DBClass.LoadListFromDatabase());
}
}
Pro on this:
Reference is continous.
The Con on this:
Reloading the list is more difficult, since it just cannot be replaced, but must be cleared/filled with reloaded items.
What is your preferred way, for what situations?
What do you see as Pro/Con for either of these to patterns?
Since this is only a general question, not for a specific problem, every answer is welcome.
Do you need the caller to be able to modify the list? If not you should consider returning IEnumerable<T> or ReadOnlyCollection instead. And even if you do, you will probably be better off making cover versions for Add/Remove so you can intercept modifications. Handing a reference to internal state is not a good idea IMO.
A third option would be to go with option 2, but to create a new instance of the Object2 type each time you need to repopulate the list. Without additional context for the question, that is the option I would select, but there may be reasons why you would want to hold on to the original instance.
I'm working on some application, that uses a TreeView control to represent business objects. Currently the link between business objects and TreeNodes is maintained through the Tag property of the TreeNode. Im not very happy with this, because I think the link is not "tight" enough. For example there could be an TreeNode object without a business object, also I want to update the TreeNode image depending on the business objact state. Therefore I derived my own special TreeNode class from TreeNode:
class ActionTreeNode : TreeNode
{
private Action mAction;
public Action Action
{ get ... }
public ActionTreeNode(Action action)
: base()
{
if (action == null) throw new ArgumentNullException("action", "Paramter action must not be null.");
mAction = action;
}
public void UpdateState()
{
switch (mAction.ActionState)
{
case ActionState.Passed:
SelectedImageIndex = 3;
ImageIndex = 3;
break;
case ActionState.Failed:
SelectedImageIndex = 2;
ImageIndex = 2;
break;
...
}
return;
}
}
With this minimal approach I have to cast every time I call a property or method of the base class that returns a TreeNode object like in "(ActionTreeNode)myNode.Parent". The solution would be to override/overwrite every method or property and return an object of ActionTreeNode type.
What do you think, is it more suitable to take the minimal approach or would you take the effort to reimplement all the methods, properties in order to avoid casting? Thanks.
I like the minimal approach. If you are worried about cluttering your code with loads of cast statements simply create a method to do it for you in one place:
private ActionTreeNode GetParent(ActionTreeNode node)
{
return node.Parent as ActionTreeNode;
}
// in some method:
ActionTreeNode parent = GetParent(someNode);
if (parent != null)
{
// the parent is an ActionTreeNode
}
Don't forget the null check on the return value though, should the parent not be an ActionTreeNode...
I think the question is how long will it take you to take the effort to make it strongly typed.
Weigh up the cost of making everythign "tight" with the cost of you and other developers having a solid platform to work with.
Without knowing more, I personally think I would strongly type it as it will also mean that any changes to your business logic such as different types stored in the tree will result in a compile failure rather than possible unknown bugs.
Suppose I have a number of related classes that all have a method like this:
protected override OnExecute()
{
this.constructorParm.BoolProperty = !this.constructorParm.BoolProperty;
}
The type of constructorParm may change (it may also be a static Setting), and the specific property will certainly change, but the type of the property will always be bool.
Suppose further that I've decided it's silly to have 8 different classes that all do the exact same thing on an implementation level- toggle a bool value. Especially when they're all related on a semantic level also (they all derive from the same Command abstract base class, which is where OnExecute() comes from).
How to I parameterize the property that I want to toggle without parameterizing the actual toggle operation itself? For example, I know I can do something like this (uncompiled):
internal class CommandX
{
Action doExecute = null;
public CommandX(Action executeAction) { this.doExecute = executeAction; }
protected override OnExecute() { this.doExecute(); }
}
// elsewhere
var b = new CommandX(() => {target.BoolProperty = !target.BoolProperty;});
but how I can I capture the toggling behavior in the class, while still accepting the writable property as a parameter? (If I pass the toggling in as a parameter, then I'm just making an over-complicated delegate.)
(I can't just pass the property in b/c bool is a value type, so I'd just be toggling a copy. I can't pass it in by ref, of course, b/c properties can't be passed by ref. I feel like there's got to be something stupid and obvious that I'm just really missing here. :) )
Context
The reason I'm doing such a simple thing in an indirect manner is actually due to the use of the GoF Command pattern in winforms. The core functionality Commands are more complex, but this small subset of Commands essentially just toggles a property that will raise PropertyChanged events elsewhere. Instead of having all these commands in separate classes, I wanted to fold them into one because they're so simple.
You could use Reflection to select which property to toggle by using the PropertyInfo class:
string propertyName = "BoolProperty";
Foo myFoo = new Foo();
Type myFooType = myFoo.GetType();
PropertyInfo prop = myFooType.GetProperty(propertyName);
prop.SetValue(myFoo, !((bool)prop.GetValue(myFoo, null)), null);
You'd only have to keep the name of the property that you'd like to toggle.
However, this would only make sense if "toggling a property" makes explicit part of your design. Otherwise, it would definately be overkill for something this basic when the "easy" solution is to just toggle the property normally.
You could probably make use of reflection to specify what property to change, but if there are a limited number of options (you mention there are 8 classes), I would recommend that you use a switch statement, and have an enumeration in the class constructor.
internal enum PropertyOption { Prop1, Prop2 }
internal class Bar {
PropertyOptiion prop;
public Bar(PropertyOption prop) {
this.prop = prop;
}
public override OnFoo() {
switch (prop) {
case PropertyOption.Prop1:
this.prop1 = !this.prop1;
break;
case PropertyOption.Prop2:
this.prop2 = !this.prop2;
break;
}
}
}
Some good answers here
I'm afraid I'm not an expert on any of these. But I think the situations are similar.
Can you refactor out a common functionality from these two methods?