| Mel's profileMelGrubb.ToBlog()BlogNetworkSkyDrive | Help |
|
|
August 15 Code Generation PresentationHere is a screencast of my recent Code Generation talk at Quick Solutions. This is our first recorded screencast, so we're a little rough at first, but I think this is pretty good for our first attempt. For the curious, I was connected to a network projector while Alexei Govorine was shadowing the screen with his laptop, and running Camtasia Studio to do the capture. this worked out nicely in that it left my laptop free to run the slides and demos without having to be concerned with the recording duties. I tried capturing the screen myself earlier in the week, and found that Camtasia slowed down the demos slightly, and made some Powerpoint fades and transitions a bit choppy. Anyway, this is my first screencast, so enjoy, and if you're one of my non-programming friends, and have no idea what I'm talking about, that's okay... you don't have to watch the whole thing... muggle. August 05 Tech Night, August 12thI’m giving a presentation on August 12th at QSI. I think it’s a pretty cool one if I must say so myself. Come learn about T4 templating and what it can do for you. What it’s doing for me at the moment is pretty flippin’ sweet, so I want to share the love, so to speak. Don’t forget to RSVP so as to ensure a decent pizza supply. Title: Practical Code Generation with T4 Description: T4, Visual Studio's built-in, template-based code generation system was introduced in VS2005 and achieved limited public acceptance in VS2008. Now, with VS2010, it is set to become a first-class citizen in many .NET solutions. T4 templates can be used to automate many repetitive coding tasks, such as boilerplate framework code or proxy generation. In this session, we'll start with the basics of code generation and advance through using T4 templates and reflection to automate the creation of customizable artifacts at virtually every tier of a typical solution. When: Wednesday, August 12, 2009 RSVP: Anji Morey @ amorey@quicksolutions.com by noon on Tuesday, August 11! Where: QSI Training Center *Friends, clients, candidates and co-workers are welcome! July 06 Who needs RowTest?I’ve heard a lot of developers bash one unit testing framework or another because of the lack of the RowTest attribute, which I beleive originated in MbUnit, at least as far as .net developers are concerned. If it came over from the Java world, well… that’s outside of my current scope and I don’t care. What bothers me is that some developers will use the presence or absence of the RowTest attribute as criteria for accepting or rejecting an entire testing framework, when in my opinion the attribute is totally unnecessary in the first place. You can achieve the same (or better) results using code that will work in ANY unit testing framework (barring the usual attribute naming differences, of course). Let me start by saying that if you want to run TestA with three different sets of input, I presume it’s because those three sets of input are each supposed to provoke a slightly different response form the test, otherwise why bother? Perhaps you are explicitly testing the edge cases to make sure that everything works as expected on either side of a boundary without blowing up. Let’s assume that we want to test some method that takes a lower and an upper bound, and lets you know whether they are valid. We write a test that looks something like the following, which takes a lower and upper bound, and a Boolean indicating whether the test should succeed or fail.
The problem here is that nothing about the input data tells me why it’s special. What is different about row 1 as opposed to row 2? It’s a contrived example, sure, but stay with me. Now do the same thing without the RowTest attribute. I hear people complaining already: “But I don’t wanna write the same test three times”. <arnold>Stop whining!</arnold> I’m not talking about wholesale copy and paste here. you just factor the guts into a non-test method. It’s easy, you’ll see. public void RangeValidatorTestHelper(int lower, int upper, bool expected) It’s a little wordier, sure, but I like wordiness, personally. Notice how the actual tests each have their own intelligent names now. I can read the test results without having to “parse in” the parameters to figure out what’s going wrong with a test now. But hey, that’s just me. June 24 IoC Auto-registrationI’ve used IoC containers on several projects now, and quite frankly never want to live without them again. They make so many things easier for me that they have become part of my way of designing. I like deciding in one place how a class will be instantiated. I like the possibility of making a change in one place an having all the instances of a class become singletons, even though that kind of change is rare. The one thing I don’t like is maintaining a “registry” class, and adding configuration for each and every class to it when I have a whole category of similar classes that should all behave in the same way. Take, for example, service proxies. Regardless of how their endpoints are configured, the code to register them with the IoC is going to look exactly the same for each one.
I’ve done some reflection-based “registration” of classes before for things like validators and workflow classes, and it saved me a lot of time. The idea is simple. Reflect over an assembly, looking for all the classes that fit a certain pattern, and add them to a list of some kind. This is usually done at application startup, so whether you’re afraid of some fictional “performance hit” associated with reflection or not, it’s only going to happen once per run anyway, and it saves a lot of tedious typing. It also automates the addition of new classes to the pattern so you don’t forget and leave anyone behind. I’ve now written something similar to handle registration of similar classes with an IoC container. This requires a base interface and a base type. We then reflect over the assembly containing the base type, and register all classes that implement an interface derived from the provided base interface. In other words, given IService and ServiceBase, automatically register IFooService/FooServiceProxy. The method looks like this:
Using it is as simple as passing the two parameters in. Here is the static constructor from an example ServiceRegistry class which registers all the service proxies for a client application. This example happens to be using a Unity container, but you could do the same thing with StructureMap, or my own Itty Bitty IoC if you want. I’ve been playing with this idea of using static constructors on an XyzRegistry class for a while, and so far it’s treating me just fine.
That’s it. All my service proxies get found and registered at startup, and I don’t have to worry about adding them by hand anymore. May 30 Book Review: Anathem by Neal StephensonHave you ever been at a party and two drunk and/or stoned guys are sitting in the corner discussing the meaning of life or the nature of existence? Would you have any interest in reading a transcript of that conversation? I didn’t think so. Now imagine that the two guys are Albert Einstein and Stephen Hawking, and the discussion is about the nature of pan-dimensional existence. Okay so now you’re more interested in the transcript, right? The only problem is that now you can’t understand a word of it. That’s kind of what reading Anathem is like. I wanted to like it, I really did, but to be honest it takes up twice the space it ought to. There’s little enough actual plot in this novel that I could retell it in less space than this review takes, but the narrative is so tangled up in its own contemplative navel-gazing that I had to continuously stop myself from yelling “Get to the friggin’ point, would you?” At the same time, standard plot elements and devices are given only the most cursory treatment. Should the main character have a love interest? No, we’ll just let him decide “I think I like Ala” before yanking her away so that he can spend the rest of the novel pining over a girl that he had previously never even gave a second thought to, nor made it to second base with. My main irritation with Anathem is the author’s heavy-handed use of invented language to immerse the reader in the world in which the non-action takes place. Plenty of authors have used invented language to gently remind the reader that they are no longer in Kansas, but Anathem spent so much time positively pummeling me with its Oz-club that it became a distraction. It’s okay to make up a few new names and/or terms here and there, but when the reader spends most of the novel saying “Now what the hell was a ‘mobe’ again?” you’ve overdone it. Fortunately the made up language becomes more sparse throughout the middle of the story but at the same time, that’s when everything stops happening, and it degenerates into the literary equivalent of a particularly uneventful road-movie. It’s like the whole Tom Bombadil section of Lord Of The Rings, but ten times as long. Chapter after chapter of absolutely nothing of any interest happening, but described in excruciating detail. I would have given up on it, but by this point finishing the novel had become personal, although I found myself "fast-forwarding” through some of the dinner conversation “messals” in which page after page is spent discussing many different wordings and explanations for what could easily have been explained just once, and more succinctly. I’ll always appreciate Neal Stephenson for writing Snow Crash and In The Beginning… Was The Command Line, but loyalty only stretches so far, and mine is now soap-bubble-thin. The ideas were fascinating, but so much time was spent on philosophical dead-ends that the whole thing cries out for editing. Did I need to witness a conversation about the most mathematically pure way to divide a cake into eight equal pieces? No, I really didn’t. (To be fair, this conversation was an appendix, but you can’t just drop footnotes and not expect me to read them.) The intricacies of how the concent’s clock is wound, and how it works the gates genuinely added to the sense of life at Saunt Edhar’s, but plenty of other orthogonal offshoots could have been left by the wayside, resulting in a tighter, more focused work. February 18 Joel Spoelsky just became irrelevantI was listening to the Stack Overflow podcast #39 last night while waiting for my daughter's basketball game to start, and I'm pretty sure Joel just flipped the bozo bit in my mind. He and Jeff Atwood were discussing test driven development, and Joel's example had to do with a button in Copilot that would change the jpeg compression level, I suppose to make screen text momentarily more legible at the expense of bandwidth. Joel then went on to complain how the resulting unit tests would dwarf the actual code.
The actual code would have been about 10 lines by Joel's estimation since all it had to do was change one of the parameters to the jpeg compression library they use on this product. The test code, however would be monstrous, requiring pre-made "after" versions of an image at varying compression levels with which to compare the results with the button in various states. He also mentioned the problem of someone else having to test these things, and the difficulties they would encounter if their jpeg library happened to be different than what Joel was using.
This exchange pointed out a couple fundamental misunderstandings about how you write unit tests. Apparantly, Joel only understands full, top-down integration tests. The idea that I would write unit tests for something like Word, for example, by checking that the individual bits of a .doc file are affected by clicking the bold button on the toolbar illustrates a complete misunderstanding of what "unit" testing means. You don't test the launch systems of our nuclear arsenal by blowing something up. See my previous post for my new favorite definition of unit testing. Bascially, I said:
That's what Joel doesn't understand. In reality, all Joel's test needed to cover was that pushing the button changes the input parameter to the compression library. You don't worry about whether the compression library works, that's not your code. Those tests belong to the component vendor who makes the compression library. If, for some insane reason, Fog Creek felt it necessary to write their own jpeg compression routines, then they are violating a couple of other closely-held principles of mine, and have thus flipped their collective bozo bits en masse. I certainly hope this isn't the case.
This basic misunderstanding of who owns what is illustrated by the second part of Joel's comment, where he talks about the testing difficulties introduced if customers jpeg libraries produce different results than whatever Fog Creek was using. Excuse me? The customer has no more business running your unit tests than you do running the tests for the jpeg library that, God willing, you didn't write in-house. Why would your customers even have your tests. Why would you have shipped them the test assemblies in the first place. They aren't going to need it (TAGNI?).
I've listened to Stack Overflow for a while, and I've found it very interesting and enlightening in most cases, but this one episode reduced my personal opinion of the hosts by several orders of magnitude. If you don't understand a subject, then either don't talk about it, or have someone on who does understand it to explain it to you. There are inexperienced developers out there who think that just because you have a podcast, then you automatically know what you're talking about. It's your responsibility as a host to not do irreperable damage to your audience by convincing them that things aren't important just because you don't understand them. This one episode has just armed a small army of developer luddites with a "get out of testing free" card that they will play to their pointy haired bosses, thus avoiding that whole nasty "career advancement" business.
Hopefully in the coming weeks some more guests will appear to set Jeff and Joel straight. If not, then I'll probably just stop listening. The bozo bit is, however, very hard to un-set. Years ago something Rockford Lhotka said flipped his bozo bit in my mind, and I still have a hard time taking him seriously today. The thing is, I can't even remember what it was that he said now. Yeah, that's how sticky the bozo bit is. January 23 Shuffle memeIt's been a while since we've done the "shuffle" meme, so I'll start it off today. The rules are simple: Put your Zune/Ipod/Media Player/Whatever in shuffle mode and write down the first 10 things it plays at you. It's okay to bail on a song if it sucks, but you still have to put it on the list.
Today, my Zune is having some pretty heavy mood swings. It's either very mellow, or very angry from one minute to the next.
And one bonus track: Meat Beat Manifesto - Edge Of No Control Pt. 2 January 22 On Unit Testing, Mocks, and IsolationThis isn't going to be news to most developers, but I just thought I'd write this down anyway. I was talking with a colleague yesterday about unit testing, and about RhinoMocks in particular, and came up with what I thought was my best explanation to date about why Mocks are important. To me, it all came down to the following sentence.
It's that "assuming ... job" part that's important. That's what the mocks or stubs are for. They're the tool that lets us focus a test on a single piece of code, excluding as much of the outside world as possible. That's what makes unit testing work. We're not saying that the code "over there" won't be tested as well. It just won't be tested "here". Having a separate test for "here" and "there" rather than one overall test for both means that if one of the two pieces break in the future, then we'll know which one it was. We've cut our number of suspects in half by testing them separately.
Talking about this reminded me of a problem a theatre director once explained to me. It's all about vocabulary. The problem isn't usually that people can't understand what you're trying to get them to do, it's that you haven't put it in the right terms for them. You can give the same instructions to three different actors, and each one will do something slightly different. Getting people to really grok what you're saying relies entirely on finding the words that mean the same thing to them as the concept you're explaining means to you.
Like I said, if you "get" unit testing, then this post isn't anything you don't already know. But maybe if you're just getting into the idea, or if you're the type who argues for integration testing because it's closer to "real world" conditions, then maybe my explanation might change your mind about how you think about testing. January 17 Framework Design Guidelines (Second Edition)I meant to write about this book a while back, but got caught up in a bunch of projects and didn't get around to it. If you haven't bought this book yet, you really should. The first edition has been an invaluable asset to me on a number of past projects, and the second edition is even better with sections on newer language and framework features such as Linq and extension methods. I've seen, read, and even written a few standards documents in my time as a professional programmer, and I think this book is the last one I'll be needing. The format of the book is one I always enjoyed, with the guidance interspersed with comments from the "peanut gallery" of Microsoft architects. These asides give you a lot of insight into the "why"s, something which a lot of standards documents are missing (I'm talking about YOU, IDesign). It's one thing to be told to do something in a particular way, but it's a lot better when you are taught why. Simple coding patterns that I wouldn't have given a second thought to have turned out to have a great impact on other aspect of my code once they were explained. The basics are covered, such as naming and formatting standards, but the book goes much further with sections about when and how to use certain interfaces, and provides some brief explanations of common design patterns as they relate to the .net framework. I'm not talking about "Visitor" or "Model View Presenter" here, I'm talking about "IDisposable"... muuuch lower level stuff. Basically, this book isn't just about what you ought to be doing, it's about explaining why Microsoft did what they did in the .net framework. It's refreshing at times in the book to find a discussion about how something was a bad choice in retrospect, or how the framework designers wished they had done something differently knowing then what they know now. I feel a lot better about my own changes of mind, and less like an amateur for not having seen the eventual solution in the beginning. After reading it, I'm more comfortable that I've made the right career decision to stick with this programming stuff. Another great asset included with this book is the DVD. It's full of training sessions and example API specifications. One of the first things I did with the previous edition was to convert all the videos to play on my Zune, and spent the next few weeks watching through them whenever I got the chance. I probably won't watch them all over again, since I think they're the same videos, but they're definitely worth the watching. December 31 Use DateTimeContext to put your code in a time warpOn 12/31/08 all the 30 gb Zunes in the whole world died en masse. This was attributed to a bug having to do with 2008 being a leap year. Because the 31st was the 366th day of the year, something in the clock code for the Zune freaked out, locked up, and earned Microsoft a lot of scorn from the Apple fanboys of the world. This started me thinking. It should be easier to test what your code will do at a particular time. Thinking aloud over Twitter, I settled on a design similar to the way TransactionScope works. You put your code inside a using statement, and it thinks it's whatever time you want. It's not quite that easy since we can't just replace the DateTime class, or at least not that I know of. If someone has some Ninja tricks that would allow us to do this, I'd be glad to hear them. In the meantime you'll have to replace all the calls to DateTime.Now and DateTime.Today with calls to similar properties on the new DateTimeContext class. If you're not IN a DateTimeContext at the time, then these methods will return the real date or time, just like you'd expect. If you wrap some code in a using DateTimeContext block, then they'll return whatever you've told them to. I dislike changing code solely for the purpose of testing, but for purposes of testaBILITY is okay. Here's a unit test I wrote that illustrates how the DateTimeContext class is used.
Notice that the Asserts that are outside of any context are comparing against Today, and the ones inside are using Now. This is just to get around the problem where the time could have changed between two retrievals. I could have asserted that the difference between the times was some negligibly small amount, but I wanted the excuse to hit both the Now and Today properties anyway. Now on to how it works. The DateTimeContext class uses Thread Local Storage to store a reference to the current instance, and provides a static "Current" property to help us get to that instance. When we ask for Now or Today, the static methods will check to see if there is an instance on the thread, and if so, they'll return what they've been told to return. If not, then they'll defer to the real DateTime values.
Each instance of the class also has a "PreviousContext" property that will remember the instance that was on the thread when it was instantiated. This lets us nest contexts, and they'll unwind properly when you've finished with them.
There are multiple constructors which mirror the most commonly-used DateTime constructors as a convenience.
Finally, there are all the fiddly IDisposable bits and destructors that make it all tick. When a DateTimeContext is disposed, it puts the previous instance back on the thread, allowing us to stack them up all we want (Or until we run out of memory). Here's the whole class. Hopefully it proves useful for someone. It should make it a lot easier to test what certain code will do on or just after certain transition/edge case days. This may not be the final version, but I couldn't stop thinking about it until I wrote it out.
Update 1/1/09: I decided to call the class DateTimeContext instead of the original DateTimeScope. It just sounded better to me personally. Also, comments about the DateTime issue "possibly" being the cause of the global Zunepocalypse were removed since that's exactly what it turned out to be in the end. December 08 Generating DataContext Proxy Classes With T4 TemplatesA while back, my friend and coworker Kris Scott posted an article about using a proxy around DataContext classes to add support for isolation/mocking for testing purposes. I won't re-hash the basic idea here, as Kris' blog entry explains it just fine. In that article he links to a Google Code project which generates these proxy classes for you. I've used it to great success on two separate projects now, but as I prepare to leave my current project, I didn't feel altogether comfortable leaving behind a dependency on an external tool that none of the other developers were familiar with. I'd been looking at Damien Guard's T4 template replacement for generating an entire replacement Linq to Sql DataContext, as well as Oleg Sych's articles regarding T4 template processing in Visual Studio 2008. This started me thinking about creating a T4 replacement for the proxy class. I spent some time this weekend taking a stab at it, and I now have a T4 template that generates the exact same thing as Kris' original program. This template adapts a few of the classes from Kris' generator, using Linq to XML in place of XML DOM code. The results are the same, but I like Linq a lot, and figured it would be worthwhile making the change as long as I was in the neighborhood. One of the interesting things about using T4 templates is that they go to work whenever you make a change to the template itself. You're can also right-click on the template and "Run Custom Tool" to re-run the generation whenever you like, but in our case we'd like the template to be re-run whenever we make a change to the .dbml file, which is going to change far more often than the template will. To accomplish this, I'll again adapt something that was working for Kris' technique. On the project he had written it for we were launching Kris' generator program as a pre-build step of the project containing the .dbml file. Some searching on the web told me that the T4 template processor is called TextTransform.exe, and can be run as a command line tool. I changed the pre-build step to something like this.
Unfortunately, the TextTransform tool's directory is not in any search path, so I've had to hard-code the entire path to the tool. This is fine for now, but if a future version of the tool is released, I'll have to remember to update the pre-build step to call the newer version. In this example, the dbml file is called AbcData.dbml, so we call the T4 template "AbcData.tt" to match. All T4 templates have a ".tt" extension, and in our case I'm following Damien Guard's lead and dynamically "figuring out" the path to the dbml by requiring the T4 template to have a similar name. The template will create a class called "AbcData.Proxy.cs". I wanted the file to be called "AbcDataProxy.cs" like Kris' original program did, but the T4 processor seems to add the extra dot whether I want it to or not. The proxy class itself is still called "AbcDataProxy", though. I won't dissect the template line by line here, but I'll point out some of the highlights. At the top of the template file we have a bunch of directives. You can get information on what they all mean off of MSDN or from Oleg's posts. Most of them are essentially "using" statements which specify the .Net libraries that our template's code will be using. The second line is where you specify what extension your resulting code should have. It's actual filename will be determined by the name of the template itself. This is where that extra dot comes from. Whether I specify the extension as ".Proxy.cs" or "Proxy.cs" the T4 processor will helpfully make sure that there's a dot there... gee, thanks.
When we run the template, it will need to be able to write to a file that in all likelihood already exists, and is under source control. To accomplish this, we'll need to make the file writeable. Visual Studio will somehow magically pick up on this and check the file out from source control, which is pretty cool, actually. We'll take the name of the template, do some string manipulation to come up with the name of the resulting file, and then remove the ReadOnly attribute from that file before continuing with the code generation.
After that, we'll load the .dbml file, which is just an XML document, and begin using Linq to XML's methods to start dissecting it, looking for the parts we're interested in.
This is where my versions of Kris' classes come into play. The ContextType and ContextFunction classes take an XElement into their constructors, and can generate the interface or proxy class signatures we'll need later on. Next, we add some boilerplate stuff to the template output like using statements, the interface header, and some methods that appear in every interface without changing. After that, we escape out to code similar to classic ASP or CodeSmith templates and include two loops which will use the ContextType and ContextFunction classes we created earlier to emit the per-table and per-function contents of the interface.
After generating the interface, similar code will create the proxy itself. Toward the bottom of the template, you'll find the declaration of the ContextType and ContextFunction classes themselves. They appear in a different kind of code block, delimited by "<#+" and "#>". Any classes your template needs can be declared in this way. I could have broken these out into a separate file and used directives to include it here, but I prefer having a single template file like this, at least at this scale. So how do we use all this?
UPDATE: For those of you with 64 bit Windows installations
Now anything that tries to use the tool using the old path will use the new path instead... TADA! Problem solved. November 03 Itty Bitty IoC (A C# IoC container in 100 lines)Since I posted my Teeny Tiny Template parser last week, I figured I'd keep going and post about my Itty Bitty IoC container as well. I'm not going to attempt to define IoC or Dependency Injection in this blog post, that's not the point. There are enough sites out there already that cover this pretty well. Go read Martin Fowler's article "Inversion of Control Containers and the Dependency Injection pattern" if you want the full story. This blog post is simply to introduce my own "ClassRegistry" class, a C# IoC container that does pretty much everything I've ever needed from an IoC container, and does it in 100 lines. This is another one of those classes I like to use as a "first resort". No it doesn't have the power of something like StructureMap, but for a lot of projects that can be overkill anyway, and when a new project is starting up it's more about establishing the pattern than nailing down specific tools. You can always switch to a different IoC container later on if you outgrow this one. I got started on this when I say Oren Eini's 15 line IoC container (here), and Ken Egozi's 15 minute response (here). They got me thinking about just how simple an IoC container could be. Oren's is interesting as an experiment, but it's a little TOO minimal for normal usage. Ken's is interesting as well, but it only does transient registrations. Mine does constructor injection for the following types of dependencies.
So, on to the code. first of all, lets get some supporting stuff out of the way. I've got a DependencyInfo class which encapsulates and describes an individual dependency using an enumeration of the supported types. I've also defined an attribute used to mark which constructor to call in the event that the choice isn't obvious (More on that later). Finally, I have two dictionaries. The first will store all the DependencyInfo objects, and the second will store actual instances of the dependencies for the "Instance" and "Singleton" dependency types.
That's all very interesting, but it doesn't actually do anything. In order for the container to return things to us, first we'll have to "register" the types we want it to handle. I've provided four Register methods, one for each of the dependency types.
The first Register method takes in a specific instance of a class. We're telling the container "If anyone asks for one of these, hand them this one". The second handles transient registrations "If anyone asks for one of these, make up a new one and give it to them". The third can be used to handle singletons by passing true as the sole argument "... make up a new one, and give back the same one from then on". The final Register method is what'll save your bacon in a lot of cases. But before I can really give a good example of how, we'll need to look at the other half of what IoC containers do, which is to hand back or "resolve" the classes you've registered. There are two methods here. The first is a generic method which is mainly for convenience. It makes the syntax for using the container much nicer. The real work is done by the second method which takes a type, and hands back an instance of that type.
I won't explain every line individually, but would like to explain the basic flow. If you ask for any unregistered type you get an error. If an instance has been cached for a type, you get that instance. This handles both the Instance and Singleton registration cases. Delegate registrations run the delegate that was originally handed in, and return the result. Assuming we haven't already returned, we'll need to actually build something, so we'll look at the type that was registered, and try to pick its "greediest" constructor. This is the constructor that takes the most parameters. If there's a tie, we can use the presence of the InjectionConstructorAttribute as a tie-breaker. If there's still a tie, then all bets are off. It won't explode, but I won't guarantee which constructor will get called either. If you ever find yourself in this situation, then you are quite definitely doing something wrong, so you get what you deserve... there, I said it. Once we've picked which constructor to use, we get its parameters, and recursively call Resolve to fill them in. Finally, in the case of a singleton registration, we remember the new instance for any future requests. Here are some examples of using the ClassRegistry in different ways. These come directly from the ClassRegistry unit tests.
Now I can explain why the "Delegate" registration type can be so useful. It all comes down to that recursive "fill in the dependency's dependencies" part. Sometimes you just need to override the normal behavior, and the delegate registration type is what will make that possible. Let's assume that our example ProductRepository class requires a Linq to Sql DataContext class in order to do its work, a NorthwindDataContext specifically. Ordinarily, I would just register the NorthwindDataContext, and let the container do the rest. The trouble is that when ClassRegistry goes to look for the "greediest" constructor, it's going to find the one that takes a connection string. Since we haven't registered what to do when someone tries to resolve "string", nor would we want to, we'll get an exception when we try to resolve NorthwindDataContext. Since NorthwindDataContext is a generated class, I can't just go in and mark the correct constructor with an attribute, either. What I'll do instead, is to tell ClassRegistry exactly what to do when someone asks for a NorthwindDataContext.
I could take the call to ConfigurationManager, and put the whole thing in the call to the NorthwindDataContext constructor, but that would make it part of the delegate that gets run each time we try to resolve NorthwindDataContext. Since this string won't change over any single "run" of the service projects, that's pretty wasteful. Instead, we'll figure out the connection string once, outside the delegate, and use the result in the registration. Note: You'll notice that the ClassRegistry doesn't have any kind of "Reset" method. That's because in real life, you should never need one. IoC registrations aren't the sort of thing that are supposed to change while an application is running. They're the sort of thing you set up once when the application starts. The only place this caused me a problem was in unit testing the container itself. Since it's a static class, once you've registered an instance of something, or resolved a singleton, you can never make it transient again. I got around this problem by creating two separate "test case" classes. One for instances and singletons, and one for transients. But like I said, this isn't something that ought to come up in the real world. October 31 Teeny Tiny TemplatesOn my current project, I need to "fill in the blanks" in some text file templates. It's nothing we haven't all done before using a series of string.Replace functions, and they work just fine, but they're not shiny enough. Also, when you think about it, each individual Replace operation iterates over the whole document again looking for the next tag to replace. I decided to make something using regular expressions instead. Something that would make just ONE pass over the document. Here's the result.
Yeah, that's the whole thing... really. To use it, you just new up a TemplateParser, add items to the TagValues dictionary, and then call ParseString, handing in the template. Here's a simple unit test that shows it in action.
Now on to the discussion. There's really only one interesting part to this whole thing, and that's the call to Regex.Replace. You can see I'm passing it a lambda expression here. This is the MatchEvaluator. Its whole job is to take each match and do something with it. It could trim spaces, make it all uppercase, anything really. In my case, I'm going to pull the tag out of the match, and look it up in the dictionary. If I find a value I'll replace the whole match with it, otherwise I'll replace it with an empty string. I suppose the regular expression (@"<%=*\s*(?<1>.*?)\s*%>") itself could use a little explaining. I've often described regular expressions as a "write-only" medium. You can look up the parts you need in a reference, string them together, and make a working RegEx, but woe unto those who try to read it after it's been created. So let's break it down into chunks.
So this looks for anything in the format <%ABC%>, and pays close attention to the "ABC" part in particular, giving it a name so that I can talk about it later. And that's it, really. It's going straight into my core library for future use. I'm not saying that this will run your enterprise, but for those times when you just need to fill in some blanks, this'll do the trick. UPDATE:
September 19 Running the Zune software on low memory machinesSo I recently upgraded to the Zune 3.0 firmware/software package, hoping that it would solve a problem I've had for a while where I would begin a sync, and it would die at about 5% complete. It would start off fast enough, but decelerate slowly until it became totally unusable at about 5%. Looking at my task list, I saw that ZuneEnc.exe was running, sometimes taking as much as 70% of my CPU, even though it is set to Low priority. My fan was running in high gear, and the computer became utterly unresponsive. My persona computer is not that strong, and it's never really bothered me. In fact, the inability to play games on it keeps me "honest" in the evenings when I'm trying to write something. ZuneEnc is the transcoder for the Zune. This is the part that takes media files that the Zune device can't play and turns them into ones that it can. In theory, it's a very good thing, but it was dragging my whole system down into the dirt. Fortunately, you can disable this from running in the background so that it only pops up when you want it to. Go to Settings -> Device -> Conversion Settings in the Zune software, and uncheck "Allow files to convert in the background". You'll need to restart teh Zune software to notice the change, but the change was dramatic for me. Now just having Zune open won't mean that files are being converted. I'll actually have to initiate a sync to cause that. This unfortunately means that I'll have to leave the computer pretty much alone when it's syncing files, but at least it won't hurt my performance when I'm just trying to listen to something while coding. I'd like to see some attention given to this issue by the Zune software team. If ZuneEnc is set to low priority, then it should get out of the way. I suspect that it is actually doing this, at least as far as processor time is concerned, but it's staking a claim to too much memory to do its processing, thus degrading the performance of everything else on the system. I've only got 1.5 gigs of ram on this box, and no immediate plans to upgrade unless some 1gb RAM sticks fall off the back of a truck in front of my house, as the money is currently allocated to other things. So the plan is to leave this unchecked, and then when I don't need the computer for a while, I'll turn it back on and just let it sit there and convert to its heart's content. I just have to remember to turn this back off before trying to do anything with the Zune software running. August 29 Accessor? We don' need no steeenking Accessor!For whatever reason, developers don't universally love the Visual-Studio-generated Accessor classes, as helpful as they may be. They do solve a lot of problems when you're writing unit tests, though. It would be nice if you could achieve the same results without having to resort to an external class. Now, through the magic of reflection, and extension methods, you can. The idea started simply enough. There are a number of places in my current project where developers (me included) have made methods public that really ought to be private or protected, just so that we can get to them for testing purposes. Then, we've simply excluded those methods from the public interface that we are using to reference those objects. We're using StructureMap to handle dependency injection, so virtually every logic class, service, and controller is being used via an interface. In our particular case, this works well, but it has still always bugged me that we're changing the behavior of classes to facilitate testing, and then depending on a condition of our environment to make that "okay". I wanted to keep those private members private, and just use reflection in the unit tests to get to the "naughty bits" that we shouldn't be exposing, but I wanted to do it without the Accessor classes that so many people seem to despise. What I wanted was to be able to get and set private fields and properties without having to go through a lot of extra Accessor class generation, and in a way that's not going to clog up my unit tests with a lot of tedious reflection code. By writing a few extension methods against object (I know, I know), I can now write unit tests that look like this: [TestMethod] public void SetPrivatePropertyValue_sets_property_value() { Target.SetPropertyValue("ReadOnlyProperty", "test"); string value = Target.ReadOnlyProperty; Assert.AreEqual("test", value); } So far I've got extensions to get/set fields and properties, and to call non-public methods. Unfortunately, I can't seem to get away from having to name the properties as "magic strings". These extensions aren't meant for "real" day-to-day coding anyway, though. They're meant to be used from unit tests, and if you rename a property or method in your code, the unit tests should barf the next time you run them anyway, so any problems shouldn't live long. I've read some interesting information on Chad Meyers blog, but haven't been able to make it work with my extension methods so far, or at least not without things getting messy. Here is my current set of reflection extension methods: public static class ReflectionHelper { private const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static; #region Field operations public static FieldInfo GetFieldInfo<TClass>(string name) { FieldInfo fieldInfo = typeof(TClass).GetField(name, bindingFlags); return fieldInfo; } public static object GetFieldValue<TClass>(this TClass instance, string fieldName) where TClass : class { if (instance == null) throw new ArgumentNullException("instance"); return GetFieldInfo<TClass>(fieldName).GetValue(instance); } public static void SetFieldValue<TClass>(this TClass instance, string fieldName, object value) where TClass : class { if (instance == null) throw new ArgumentNullException("instance"); instance.GetType().GetField(fieldName, bindingFlags).SetValue(instance, value); } #endregion #region Property operations public static PropertyInfo GetPropertyInfo<TClass>(string name) { PropertyInfo result = typeof(TClass).GetProperty(name, bindingFlags); return result; } public static object GetPropertyValue<TClass>(this TClass instance, string propertyName) where TClass : class { if (instance == null) throw new ArgumentNullException("instance"); return GetPropertyInfo<TClass>(propertyName).GetValue(instance, null); } public static object GetPropertyValue<TClass>(this TClass instance, string propertyName, object[] index) where TClass : class { if (instance == null) throw new ArgumentNullException("instance"); return GetPropertyInfo<TClass>(propertyName).GetValue(instance, index); } public static void SetPropertyValue<TClass>(this TClass instance, string propertyName, object value) where TClass : class { if (instance == null) throw new ArgumentNullException("instance"); instance.GetType().GetProperty(propertyName, bindingFlags).SetValue(instance, value, null); } public static void SetPropertyValue<TClass>(this TClass instance, string propertyName, object value, object[] index) where TClass : class { if (instance == null) throw new ArgumentNullException("instance"); instance.GetType().GetProperty(propertyName, bindingFlags).SetValue(instance, value, index); } #endregion #region Method operations public static MethodInfo GetMethodInfo<TClass>(string methodName) { MethodInfo result = typeof(TClass).GetMethod(methodName, bindingFlags); return result; } public static object CallMethod<TClass>(this TClass instance, string methodName) where TClass : class { if (instance == null) throw new ArgumentNullException("instance"); return instance.GetType().GetMethod(methodName, bindingFlags).Invoke(instance, null); } public static object CallMethod<TClass>(this TClass instance, string methodName, params object[] parameters) where TClass : class { if(instance==null) throw new ArgumentNullException("instance"); return instance.GetType().GetMethod(methodName, bindingFlags).Invoke(instance, parameters); } #endregion } I'll probably end up adding more later, but this is fine for my current needs.
July 15 Linq, Like, Mocks, and Expression TreesOn my current project, we're using Linq to SQL as our data layer. Without going into unnecessary detail about the whys and hows of our architecture, I'd like to describe a couple problems we encountered, and how we solved them. Problem #1: Mocking a DataContext for testing purposes: Problem #2: Performing a SQL "Like" query using Linq syntax: Solution #1: Use the SqlMethods class' Like method. list = list.Where(o => SqlMethods.Like(o.LastName, pattern)) Simple, right? Well, technically, the SqlMethods class wasn't really meant for public consumption. The documentation even says "This API supports the .NET Framework infrastructure and is not intended to be used directly from your code." But it is public and documented, so Microsoft will probably leave it alone. Seems safe enough to me, right? Problem #3: Testing it: We could write our tests so that we only performed limited searches with no wildcards, but this isn't really testing the real-world usage of our code. We could also write our searches so that by throwing a switch behind the scenes, it would replace the calls to SqlMethods with something that works on in-memory lists, such as a RegEx match. This is fragile, however, because you have to keep two code branches in sync, one of which is only used for unit testing anyway. What we need is a way to do this automatically, to take a query and change it depending on the environment it's running in. Then, once we're satisfied that this translation works (by unit testing it, naturally), we can take it for granted, plug it in everywhere, and never be bothered by this problem again. Since the problem with mocking DataContexts has now been solved, I started re-examining this issue. In concept, it's very simple. Walk the expression tree used by a query, and swap out the calls to SqlMethod.Like with something that works on in-memory lists. Simple, right? Well, it would be if Microsoft hadn't gone to great lengths to keep you from doing exactly what we're about to do. First of all, Linq expression trees are immutable, so you can't change anything about them. Secondly, even if you managed to change the expression tree, the "expression" property of IQueryable is a get-only property. This second problem pales in comparison to the first since we can use the magic of reflection to set even the most unsettable of fields. The answer to the first, harder question came from an MSDN post entitled "How to: Modify Expression Trees" (http://msdn.microsoft.com/en-us/library/bb546136.aspx). The technique is simple: You use an expression tree "Visitor" (see http://msdn.microsoft.com/en-us/library/bb882521.aspx) to make a copy of the original expression tree, changing certain pieces as you go. The example in the article changed all the Ands (&&) to Ors(||) in a simple query, so why not change all the calls from SqlMethods.Like to something else? I inherited a class from ExpressionVisitor and called it SqlMethodExpressionFixer (What, you got a better name?), and overrode the VisitMethodCall method. This will allow me to intercept all the MethodCall expressions in the tree, examine them to see if they're calls to SqlMethods.Like, and substitute calls to my own Like method instead which just so happens to take the exact same parameters as SqlMethods.Like (Clever, that bit, eh?). Here is the SqlMethodExpressionFixer class: public class SqlMethodExpressionFixer : ExpressionVisitor { public Expression Modify(Expression expression) { return Visit(expression); } protected override Expression VisitMethodCall(MethodCallExpression expression) { Expression result; MethodInfo mi = expression.Method; if ((mi.DeclaringType == typeof(System.Data.Linq.SqlClient.SqlMethods)) && (mi.Name == "Like")) { MethodInfo likeMethodInfo = GetType().GetMethod("Like"); IEnumerable<Expression> args = VisitExpressionList(expression.Arguments); result = Expression.Call(likeMethodInfo, args.ToArray()); } else { result = base.VisitMethodCall(expression); } return result; } public static bool Like(string matchExpression, string pattern) { pattern = Regex.Escape(pattern); pattern = pattern.Replace("%", ".*?").Replace("_", "."); pattern = pattern.Replace(@"\[", "[").Replace(@"\]", "]").Replace(@"\^", "^"); return Regex.IsMatch(matchExpression, pattern); } } Now that we have a modified copy of the original expression, all that's left is to substitute it for the original expression whenever we want to run a query with a "Like" in it against an in-memory list. Fortunately, that's pretty easy to do as well. Given an IQueryable instance, we can figure out whether it's a database or in-memory source simply by examining its base type. If it's EnumerableQuery, we're dealing with an in-memory data source such as a List, and we'll substitute the modified expression via reflection. It it's anything else, such as a System.Data.Linq.DataQuery, we'll leave it alone. Here is a function to do that for you: protected void FixQuery<T>(IQueryable<T> input) { Type inputType = input.GetType(); if (inputType.BaseType.FullName == "System.Linq.EnumerableQuery") { SqlMethodExpressionFixer fixer = new SqlMethodExpressionFixer(); System.Linq.Expressions.Expression expression = fixer.Modify(input.Expression); FieldInfo fi = inputType.GetField("expression", BindingFlags.NonPublic | BindingFlags.Instance); fi.SetValue(input, expression); } } I don't know about you, but this is pretty freakin' awesome if you ask me. We can now fully unit-test our Linq-based data layer without having to hit the database at all. June 03 In the name of the suckI am watching "In the Name of the King" right now... and it's terrible, just terrible. Truly awful. I mean really, really bad. I'm not saying it's as bad as "Barbarella" or "Plan 9", but it's right up there. I might rank it somewhere on a par with "Killer Klowns from Outer Space". It's extremely derivative of other, better movies like "Lord of the Rings" down to the design and staging of certain "Good Wizard vs. Bad Wizard" scenes. It's poorly acted, shot, written, and conceived in general. The characters are all cookie-cutter standards. The continuity sucks. Gallian's costumes in particular are way out of the time period, and I'm sorry, but I'm pretty sure that not all medieval military generals were black. In fact, I'm thinking that was probably pretty rare in those days. One thing puzzled me more than anything else about this movie; the casting. I can see Burt Reynolds needing the work and the money, so no blame goes to him, but the casting director needs shot. It's "Robin Hood: Prince of Theives" all over again. Obviously at some point in some meeting, some idiot with too much influence piped up and said something to the effect of "I don't think the audience will notice that everyone in the movie has a different accent". He's the effin KING, though... find someone kingly. I grew up watching him play the Bandit, I simply cannot accept him in a position of authority. That's just the way it is. Ray Liotta is also blameless on this one. I'd give him a pass because he needs the money, but pure evil is just not his thing. SMARM is his true calling. Backstabbing bad guys are his forte, not in-your-face evil guys. He's just too friendly looking for that... sorry dude. Jason Statham hasn't quite made his fortune yet, but I probably wouldn't have picked this film at this point in my career if I were him. If he was looking to broaden his acting resume away from badass criminals, then I'd advise broadening in a different direction... I'm just sayin'. Matthew Lillard, though one of my favorite actors in general, probably wants a little work these days, but I think the money from "Scooby Doo" should still have enough mileage on it that he could have given this one a pass. Maybe this one looked better on paper than it does on screen, but still, he's gotta take some of the blame on this one. Come on, man, you were Stevo in "SLC Punk!", you can do better than this. Ron Perlman, that's a little harder to take. I mean he's got Hellboy 2 coming up, and about a bazillion video game voiceovers on his resume. He is NOT hurting for work, I wouldn't think, unless he's got some money-eating drug or gambling problem that I haven't heard of. The most incredible WTF in the whole casting mess is seeing John Rhys-Davies. Doesn't he have F-you money after the Lord of the Rings trilogy? What does he need a part in THIS steaming pile for? You we're Gimli for chrissakes, have some pride will ya? As a side note, this role DID give him the chance to parade his creepy severed finger in front of a zoomed-in camera. That counts for something, I guess. On the whole, this movie wasn't quite bad enough to make me turn away in disgust. "The Stupids" is still the only movie ever to have been THAT bad. We did put the DVD player into overdrive to make it go away faster, though, and even then I wanted the last hour and a half of my life back. May 30 Resharper, day whatever it isI just have to say that since installing the "stable" build 804, my Intellisense has gone completely down the drain. It doesn't pop up on its own anymore, and I've probably hit Ctrl-Space more times in the last week than the previous year. Other than that, the experience has been great. I had one minor argument over an "unused" field that it wanted to remove. Unfortunately the act of retrieving that value was integral to the unit test where it lived. THAT one took a little while to figure out, since the failure it caused didn't have to do with that value in any way. Lesson learned... don't always take R#'s word for what is or isn't needed inside a RhinoMock record block. May 23 Communication ErrorJust in case "poonamb" reads this... I'd love to reply to your question, but Live won't let me. I tried but got the error "You can't send or reply to this person because of their communication settings." To answer your question, however. I would guess that the problem with saving your ruleset to the database is right around this area here:
You're making a call to SerializeRuleSet, but not doing anything with the answer. You need to take the result of SerializeRuleSet, which will be a string, and save it off to the database in the same table you load it from elsewhere in your code. |
|
|