Dave Burke : Freelance .NET Web Developer specializing in Online Communities

Using Reflection to promote usercontrol re-use

For a while now I've been using pop-out subforms like the one circled below.  It's there when you need it, then poof, gone again when you don't.  These are standalone usercontrols that I've re-used to a limited degree in various web pages, but was complicating re-use by not using reflection from the get-go.  So I went that route today and wanted to slap some code on this blog again.

A quick and dirty approach to re-using the user controls is to simply grab the parent page name, cast to it's base class, and call the parent method, like so:

string parent = HttpContext.Current.Request.ServerVariables["SCRIPT_NAME"].ToString().ToLower();
switch (parent)
{
 case "/wizprojadd.aspx":
  ((wizprojadd) Parent.Page).ShowForm();
  break;
 case "/wizprojupd.aspx":
  ((wizprojupd) Parent.Page).ShowForm();
  break;
 etc...
}

That works fine with a limited number of parent pages, like 2, but I now wanted to use the usercontrol in 4 other pages.  The switch approach wasn't going to cut it. 

Enter reflection. 

Reflection allows for a single statement to obtain the parent object type and invoke a method.  The only caveat is that all parent pages have the same method, which in my case they do.

Type parentType = this.Parent.Page.GetType();
parentType.InvokeMember("ShowForm",System.Reflection.BindingFlags.InvokeMethod, null, this.Parent.Page, null);

Mikey likes reflection.

 

Comments (7) | Post RSS RSS comment feed

Posted on 11/21/2005 9:02:00 PM by Dave Burke
Categories: .NET
Tags: no tags for this post

Related posts

Comments (7) -

11/23/2005 11:03:47 AM Permalink

I am trying to understand this and use. Can you please elobrate more or provide an example of how this applies to user controls.

Thanks,
Srinivas.

Kevin |

11/29/2005 1:48:11 PM Permalink

Hi Dave,

Yeah, I use these methods often. Quite cool stuff. However, more often, I tend to use a common base page class. I can wrap other stuff there, but it mainly makes for easy syntax to reference the parent - of course code specific to the parent, such as a call to some method to load a specific usercontrol, but I tend to just add a use placeholders and load the control in at runtime. Of course, using reflection to access parent methods or properties sure does make for some clean code.

Good stuff.

-Ryan

Ryan Farley |

11/29/2005 6:54:34 PM Permalink

Ryan, you're right.  A base page class can yield some powerful benefits.  Reflection is powerful stuff, too, but the base class approach seems to yield more extended productivity benefits.  I'll have to admit that I only use Reflection when I need to do something, not to be economical or smart in my logic.  Thanks for your comments.

daveburke |

12/9/2005 2:46:42 PM Permalink

Dave, I really like this approach, but in my case I dont really know if it would work.. I am doing almost the same thing as you.. could you help?

instead of calling a method.. i have a property that is the same in all of the pages..

ucpage is gotten from the database, depending on what menu item they click on

public void GetPage(string pagename,int tabid)
{
  switch (tabid)
  {
    case 1:
              myControl = (Control)LoadControl(pagename+ ".ascx");
             ((MyClassName)myControl).AssetId = id;

   case 2:
              myControl = (Control)LoadControl(pagename+ ".ascx");
             ((MyClassName2)myControl).AssetId = id;
   ... etc

  }
}

but what would be ideal is if I could actually use reflection (I dont know how)
to do this

public void GetPage(string ucpage,object MyClassName)
{
myControl = (Control)LoadControl(ucpage + ".ascx");
((MyClassName)myControl).AssetId = id;
location.Controls.Add(myControl);
}


and have MyClassName be dynamic..
is this possible???

Thanks.

Doug

Doug |

12/9/2005 5:24:18 PM Permalink

Doug,  I looked at your code a while and didn't see an obvious solution.  It's a great refactoring case though, and I might have to blog on it.  Sorry I couldn't send some code joy back your way.  Hopefully soon.  Cheers!

daveburke |

12/12/2005 8:15:54 AM Permalink

Dave, the answer was right in front of me..

reflection, would be nice if possible but i went another route.. i created an interface for my property..

public interface IMyInterface
{
    int GetProperty();
    void SetProperty(int id);
}

then in my user control I inherited from IMyInterface
and created my get;set methods per the interface and to my surpsise it worked.

public void GetPage(string ucpage)
{
myControl = (Control)LoadControl(ucpage + ".ascx");
((IMyInterface)myControl).SetProperty(id);
location.Controls.Add(myControl);
}

*side note.. I am still looking into reflection ;) *

Doug |

12/12/2005 1:08:04 PM Permalink

Doug, that is so boss!  Even though it seems like a simple solution "right in front of you" it was still a VERY smart approach BECAUSE it was so simple.  I never would have thought of using an Interface for the controls.  Thanks so much for sharing your solution with me.  

daveburke |


Powered by BlogEngine.NET 2.0.0.36
Theme by Dave Burke