Thursday, April 28, 2005


I've published a project at ProjectDistributor called Eronel.Common. It's a personal library I've come up with through thinking about useful things for my own projects in addition to what I could use at work.

Currently it revolves mostly around the XmlActivator class since I really needed something like that at work, I've talked about it in the past, it was a small/doable project, and it was just plain fun. :)

My current progress on it is: The next release (1.3) should be out by Monday. I've introduced the CasingStrategies enum which lets you choose between Insensitive, CamelCased, and ExactMatch (to match XmlNode names to MemberInfos in the XmlActivator). I plan to add IDictionary support next, and that's probably it before release. My one static library is called Utility. It's a catch-all for methods that are short, but useful, and I can't think of a good factoring for them as objects. Over time the methods often grow in functionality, or several are added together, and then as a whole they make more sense and I factor them out into their own classes. In my current build I've added the Console helper mentioned in the previous post. I'm not sure what other functionality I want to include in the XmlActivator, so this mini-project (the class, not the library) may be nearing the end.

I had originally thought I might add constructors and method invocations to it, but as it evolves, that seems less appropriate. I'll probably add constructors anyways. It shouldn't be hard, and it removes the current constraint of requiring a default constructor. I might also add support for non-public members. Besides that though, I think it's pretty robust.

One thing I don't have for it right now are a lot of obvious use-cases. I've used it mostly for configuration, though it's been used at work in a prototype parser I think is actually really neat. To use it in configuration right now you have to load up the Xml manually though. I wrote a TypedConfigurationSectionHandler at work to let me just do stuff like the following:

MailSettings settings = (MailSettings) ConfigurationSettings.GetConfig("mailSettings");

It's a lot cleaner IMO than using App.Config. I know VS2005 makes this kind of thing a lot easier, but I don't like the Xml it produces, so I'll probably try and adapt it to my own preferences when I find the time. Plus we're probably a year off from doing much at all with c#2 at work so in the meantime this is pretty useful for me personally.

Going back to that parsing app, it was actually a combination of the TypedConfigurationSectionHandler, XmlActivator, RegexActivator, and a class I wrote called the RegexStreamParser. That last one I'm pretty proud of. It lets you do things like this:

void Run() {
RegexStreamParser parser = new RegexStreamParser("invoices.txt", "(?<data>^begin\sinvoice.*\r\n(^.*\r\n)*?^end\sinvoice)");
parser.FoundMatch += new FoundMatchEventHandler(this.ProcessMatch);

void ProcessMatch(RegexStreamParser parser, Match match) {
using(ISession session = Database.GetSession()) {
Invoice invoice = (Invoice) RegexActivator.CreateInstance(typeof(Invoice), parser.Expression, match);

So using NHibernate, and the custom classes, I can write parsers for multi-Gigabyte files. The RegexStreamParser uses another class internally that buffers a file, allows you to resize the buffer on the fly, allows you to advance the buffer n-number of bytes, and allows exposes the buffered byte[] array in a property; this lets me keep memory usage low even on huge files and still be 99.99999999999999999999999% sure that I don't miss any possible matches since a single match spanning more than double the default buffer (it auto-expands/advances in 10% increments (up to 2x for expansions) if no match is found) of 5MB would be insane. Anyways, the point is I can write some pretty wicked, (and performant) parsers for large files with only what, a dozen lines of code in a simple case like above? Like I said, I'm pretty proud of it. :)

So that's probably the direction I'll head with the library after v1.3. Add more examples, and build some "support" classes (including the configSectionHandler, and hopefully a spiffy new implementation of a RegexStreamParser).

After that I might get around to finishing up the UIBroker since I'm over the configuration hump now, and it's already been half-way rewritten anyways. Hard to get motivated about something I don't use though (since I don't really do any business Forms development right now) and don't get any feedback on. :( We'll see...
Comments: Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?