Friday, October 10, 2008

Daily humor

I found this on Stack Overflow and started thinking of all of my comments in my code. Which are funny and which make no sense at all. If anyone actually reads my blog, what's some of your favor comments or code snippets that make you chuckle?

Wednesday, July 23, 2008

Reflection, Dynamically In C#

On the current project I am working at my job, I need to call web services dynamically. What I am trying to do is add additional functionality to a web page that receives its data from several web services. The web services are called through a proxy web service that puts the data into an XML format that is then past on to the web page and parsed through XSLT transforms into HTML. What I want to do is to be able to add a web service at most anytime without having to touch the web page. All of the web page configuration is stored in a table, so getting a new web service added is simple enough in that all I need to do is update the proxy web service and add the configuration to the database.

To do all of this, I need to be able to call the methods dynamically using Reflection.

Here's how:
In my application, I use a criteria (or request) object to pass in parameters to the method and a response object on the return. So, here are those objects:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
namespace Namespace
{
    public class Request
    {
        public Request() { }

        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        private string message;

        public string Message
        {
            get { return message; }
            set { message = value; }
        }
    }
}


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
namespace Namespace
{
    public class Response
    {
        public Response() { }

        private string name;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        private string message;

        public string Message
        {
            get { return message; }
            set { message = value; }
        }
    }
}

Next up, we have our class which has the method we are going to call.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
namespace Namespace
{
    public class DisplayName
    {
        public DisplayName() { }

        public Response Write(Request req)
        {
            // Run once just to show we are actually doing something.
            Console.WriteLine(string.Format("{0}: {1}", req.Name, req.Message));
            Response resp = new Response();
            resp.Name = req.Name;
            resp.Message = req.Message;
            return resp;
        }
    }
}

Finally, our method to process our dynamic call.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System;
using System.Reflection;
 
class ReflectionSample
{
    static void Main()
    {
        // Get our assembly loaded.
        Assembly asm = Assembly.Load("Namespace");
        
        // Define our main type. This is the type that 
        // we will use to get our actual object.
        Type mainType = asm.GetType("Namespace.DisplayName");
        
        // Create our object based on the type we defined
        // in the last step.
        object obj = Activator.CreateInstance(mainType);
 
        // Now, we define our request type. The request object
        // is in the same assembly.
        System.Type reqTyp = asm.GetType("Namespace.Request");
        
        // Next, create our request object. 
        object reqObj = Activator.CreateInstance(reqTyp);
        
        // After we create our object, we set the properties.
        // In my actual application, these properties are set
        // via a loop, assuming multiple dynamic properties.
        PropertyInfo piName = reqTyp.GetProperty("Name");
        piName.SetValue(reqObj, "John", null);
        PropertyInfo piMess = reqTyp.GetProperty("Message");
        piMess.SetValue(reqObj, "Hello", null);
 
        // The next step is to create the array of parameters
        // we need to pass into the method we will be calling.
        // In the case of my application, we only need one.
        System.Type[] prmTyp = new System.Type[1];
        prmTyp.SetValue(reqTyp, 0);
        
        // The next step is to get our MethodInfo object.
        // We pass in to GetMethod the name of the method
        // and the parameter type list.
        MethodInfo mi = mainType.GetMethod("Write", prmTyp);
 
        // Next, we create our actual parameter array.
        object[] prm = new object[1];
        
        // In this case we only have one parameter, so 
        // we set it as our request object.
        prm.SetValue(reqObj, 0);
 
        // Here is where we get tricky. Since we are trying to be
        // dynamic with this process, we don't want to assume a 
        // definitive type for our return type. Also, in my application
        // I use response objects that contain multiple properties,
        // this makes passing multiple properties back easier.
        System.Type respType = asm.GetType(mi.ReturnType.ToString());
        
        // Now, we create an object of our return type.
        object respObj = Activator.CreateInstance(respType);
        
        // Finally, we Invoke our method passing in the parameter array.
        respObj = mi.Invoke(obj, prm);
 
        // This is where we can parse through the properties in the 
        // response object. This is similar to the setting of the 
        // request properties, but there are additional Reflection 
        // methods to parse these dynamically. Here, I'll just use
        // predefned properties.
        PropertyInfo piRespName = respType.GetProperty("Name");
        string name = piRespName.GetValue(respObj, null).ToString();
        PropertyInfo piRespMessage = respType.GetProperty("Message");
        string message = piRespMessage.GetValue(respObj, null).ToString();
 
        // Prove we actualy did something.
        Console.WriteLine(string.Format("{0}: {1}", name, message));
    }

I hope this little sample helps someone else in their struggle to dynamically call code in .NET. Translation to VB shouldn't be too difficult. And as far as I know, this should work in all versions of .NET from 1.0 to 3.5.

Friday, June 6, 2008

Visual Studio Debugging with Siteminder

I've seen a few sites mentioning techniques for debugging within a Siteminder world.

This may be a little out dated since it uses Visual Studio 2003, but I'm pretty sure the technique is the same.

Without further ado, here's the steps to do debugging:

  1. Make sure Visual Studio is not running. It's not mandatory, but it makes it an easier approach.
  2. Disable Siteminder. This is usually done via config file called WebAgent.conf and is generally located in C:\Program Files\netegrity\webagent\bin\IIS\. Look for a line that looks like EnableWebAgent="YES". Change "YES" to "NO". Note: Case is VERY important!
  3. Restart IIS. Normally, this is done through the IIS management console, but a reboot will also work. However, that approach won't work later on.
  4. Start your Visual Studio instance and your Siteminder protected project.
  5. Next, after the project has fully loaded, change the "NO" back to "YES" and restart IIS. (See why rebooting doesn't work?)
  6. Now, debug using "Attach to process" and attach to the ASP.NET worker process for your Windows version.

This is a rather simplistic approach, but it works very effectively. It's a pain, but once you get used to it, it becomes second nature. One of these days, I'd like to write a script that automates this, but for now I'll settle for the extra manual steps.

Happy coding!

Update:

In VS 2008, most of these steps are not needed. In particular, steps 1 through 5 are not needed, You just need to make sure that Siteminder is enabled and you attach to the ASP.NET worker process running through IIS. This will not work in the "built in" web server in VS 2008.

Good luck!

Monday, February 18, 2008

ecto Templates

I found ecto to be quite a useful tool to view my blog entries in some sort of representation of my template. However, I am using 3.0b33 and after setting up my CSS to make the preview look like my blog template, I noticed that I had removed some CSS that ecto defines for itself. The problem here is that the title now is in the same style as the rest of my blog. Not good.

After finding this blog entry by Melvin Rivera that described the features of ecto, I found some of the necessary elements to restore the title section of the preview. This image shows the CSS I found on another image from Melvin.

200802180424.jpg

Thanks, Melvin!

Friday, January 25, 2008

Tools of my trade

For the record, tools are important. The tools you use should reflect your style of work and should become part of everything you do. Using the right tool for the job is most important. You wouldn't necessarily use a hammer to change a light bulb, or a chainsaw to open your mail, so why would you use a Windows tool to write a blog when you are on a Mac?

Here's what I have tentatively settled on for tools while writing this blog:

  • ecto - Desktop blogging software. I'm familiar with a few Windows based apps, but being a recent Mac convert, I felt it necessary to stay native to Mac. I'm currently writing this with the version 3 beta for OS X 10.4 and 10.5 which is a 21 day trial with a $17.95 price tag.
  • w.bloggar - Freeware PORTABLE Windows based desktop blogging tool. I can also blog at work when I have a few moments.
  • c# code format - By day, I'm a C# ASP.NET programmer, and since this blog will more than likely lean toward that topic, a code formatter is necessary. It's free, and easy. I don't need a whole lot of fancy stuff right at this minute, and I don't have time to write my own, so I'll use this.
  • Blogger - Duh. Yeah, there are other blog hosts out there, but this one I'm familiar with. If I could find a free host that uses dasBlog, I'd jump on it in a heartbeat.

That's my initial list of tools. I looked into such things as iWork '08's Pages and iLife's iWeb, but didn't see anything that would fit my needs. So, I'll stick with these for now and report my findings as I go along.

Next: Becoming a website (blog) layout designer.

UPDATE: I recently purchased ecto. It's pretty good for what I want to use for my blog. And as far as using w.bloggar and ecto together, if I'm doing something at work, I'll have to save the post as a draft to blogger then download it at home with ecto. Kinda rude, but it'll work 'til I get a Mac at work. (Like THAT will EVER happen...)

Thursday, January 24, 2008

This post is dedicated to Mr. Atwood

This first post goes to Jeff Atwood. Without his recent speaking engagement in Montreal at CUSEC and the PowerPoint presentation he offered from that engagement, I probably would have continued down my road of just reading everyone else's blogs and never contributing any thoughts of my own except for a few comments here and there.

Well, no more. I do have something to say. I do have something to contribute. So contribute I will.

For those who will read this post, I hope I have somehow sparked an interest even though I haven't posted anything but my initial intent. I don't expect much from this blog, but if I can help someone else achieve a goal, then I have done a good job. And if I don't help someone, I hope I entertain you.

UPDATE: The preceding posts were imported from a previous blog I had. I decided to just consolidate and make this all one happy blog...