December 2004 - Posts

Using Reflection to call an overloaded method on a dynamically loaded assembly

I had some fun today! I have a factory class for database access (it handles the creation of classes from either System.Data.SqlClient or Oracle's Oracle.DataAccess). The Oracle.DataAccess assembly is dynamically loaded if it's needed. Consequently, I use reflection when I need to interact with the Oracle types.

Today, I had to call an overloaded method on the OracleParameterCollection object. The tricky part was that the second parameter was of a specific type -- OracleDbType (Oracle decided the System.Data.DbType wasn't good enough for them and had to make their own). Anyway, I needed to call:

OracleParameterCollection.Add(string name, OracleDbType dataType, object value, ParameterDirection direction);

For this particular case, I needed to pass OracelDbType.RefCursor for the second parameter -- via reflection. After a bit of trial & error along with googling, I finally got it! In the code below, "oracleDA" is an Assembly instance which references the dynamically loaded Oracle.DataAccess.DLL and "cmd" is my IDbCommand object which contains the Parameters collection:

// get the type info for an OracleDbType
Type oracleDBType = oracleDA.GetType("Oracle.DataAccess.Client.OracleDbType");

// get a reference to the "RefCursor" member
FieldInfo fi  = oracleDBType.GetField("RefCursor");

// get the type info for the OracelParameterCollection
Type oraParams = oracleDA.GetType("Oracle.DataAccess.Client.OracleParameterCollection");

// find the particular overloaded method we want to execute
MethodInfo m = oraParams.GetMethod("Add", new Type[] {typeof(string), oracleDBType, typeof(object), typeof(ParameterDirection)});

// call the method to add the parameter
m.Invoke(cmd.Parameters, new object[] { name, fi.GetValue(null), null, ParameterDirection.Output});
Posted by PSteele | with no comments

SQL Server 2000 Enterprise Manager Tip

This is too cool! From Scott Mitchell's blog:

...from the Tables listing, hit Ctrl+C on a table name and then go to a text editor and hit Ctrl+V and get the appropriate CREATE TABLE SQL syntax for the “copied” table (which includes constraints).
Posted by PSteele | 1 comment(s)

RSS Feed made simple

Here's a great introductory article on creating an RSS feed for your site. This is basically the skeleton I used to add an RSS feed to our local user group's site.
Posted by PSteele | with no comments

A Great time at GLUGNET

On Thursday I did my COM Interop presentation for the Greater Lansing User Group .NET. I had a great time! They have a really nice group of people there. Good pizza and good prizes (an XBox!). Unfortunately, presenters were not eligible... :)

A couple of things I took away from my presentation:
  • Book Exchange: Their user group keeps a collection of books that other members have donated. Every month the collection is available to other members. Need a book? Grab one. Got an old book that is of no use to you anymore? Bring it in and add it to the collection. Very cool idea!
  • At the end of the meeting, they had a quick session of "5 Technology Terms" -- five buzzwords that are introduced to the group and talked about for just a couple of minutes. Thursday's list included RSS, SOA and O/R Mappers.
  • Lastly, I need to do more presentations. Sometimes I get too excited about a certain question and I either talk too fast or get off on a tangent. Practice, practice, practice...
Posted by PSteele | with no comments

Why you can't unload an assembly

Josh Holmes and I had dinner with Chris Kinsman last night. He's in town for our .NET User Group meeting tonight. One of the topics that came up was unloading an assembly and the need for a separate AppDomain. We all remembered that there were some blog posts about this but couldn't recall details. I did some googling today and found a couple of relevant posts:

Jason Zander: Why isn't there an Assembly.Unload method?

Suzanne Cook: Unloading an Assembly.

Posted by PSteele | 3 comment(s)

Whew! It's finally over!

Windows Automatic Update has been bugging me for a couple of months now to install the XP SP2 upgrade. I've been putting it off but tonight I decided I'd finally just get it over with and install it. It took almost 45 minutes to perform the update! I remember doing this on my desktop a week or so ago and it only took around 10 or 15 minutes. I guess thats the different between a 2-month old 2.5 GHZ desktop and a 2-year old 1.8 GHZ laptop... :)
Posted by PSteele | 2 comment(s)

Controlling log4net output

If you've used log4net before, you know it's a simple and easy way to add some pretty powerful logging capabilities to your application. I recently had log4net configured to log to both a text file and the console. I had the logging level configured for all messages, but I didn't want everything going to the console. After some digging through the docs I found out that you can add the "Threshold" parameter to an appender to control the logging level for a single appender:

<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
    <param name="Threshold" value="INFO" />
    <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
    </layout>
</appender>

Blogged so I don't forget it! :)

Posted by PSteele | with no comments

Scripting a SQL 2000 Database

Local .NET guru (and VP of our .NET User Group) Josh Holmes pointed me to a handy little utility for scripting an entire SQL 2000 database (objects + data). I've used it a few times and it's a pretty neat way to pass around a database.
Posted by PSteele | with no comments

Naming threads from the thread pool

I was doing some multithreaded programming today and ran into a small problem. While googling for a fix, I found a very interesting item from earlier this year: Be careful naming threads that come from the thread pool (via the asynchronous programming model):

Underneath the hood [...] the CLR rips a thread from from the CLR's thread pool. When the method completes, the thread happily returns to the pool to finish its Pina Colada. Eventually, that thread will resurface, and that's where the problem arises.

You can change the name of a thread, but you can only change it once.If you try to change it again, you're greeted with an InvalidOperationException. When a thread is returned to the thread pool, it holds onto its name. Its happy to have a sense of identity and will hold onto it even when it resurfaces to execute another method.

The original article also posts the workaround.

Posted by PSteele | 1 comment(s)

Ian Griffiths on Delegates and Events

In response to a question on the Developmentor WinForms mailing list, Ian Griffiths had a great introductory explanation on delegates and events.

Posted by PSteele | with no comments
More Posts Next page »