| |
| |
|
LATEST POSTS
Tuesday, October 30, 2007
Oy vay, the hillbilly has to be more careful adding Part 1 to the beginning of a post. Too many implications about his commitment involved. This is a follow up to a post I did to help guide new MonoRailers through the Timok sample application. If you're just joining us, or have hit me from a random search engine (oh, let's just say it: Google), the intent is to help get up to speed with MonoRail by explaining the steps one might go through when looking through a sample application. I haven't been diving too deeply into the topics because I'm not really a deep-diver by nature, unless it is required. Scared I might get the coding equivalent of the bends. A friendly reminder/disclosure/EULA that, for the most part, I'll avoid any "I think"s and "It looks like"s and "My guess is"es for the sake of readability. Consider this your unqualified qualification that anything I say here is the result of my own investigations with a liberal helping of my previous web experience. When we left off, we had gone through how MonoRail routes requests to an appropriate controller and how that controller determines which HTML to render on the page. We walked through a request to /home/index.rails which led us to the default.vm layout in the Views/layouts folder and the index.vm view in the Views/Home folder in Timok.Rbr.Portal.Web. index.vm contains the HTML that will be rendered within the default.vm layout (akin to a "master page"). But before we div---er, wade into index.vm, we need to back up a bit. I tried to navigate to /home/index.rails but was redirected to a login page. WHAT GIVES?!? Open up HomeController.cs again and notice that it derives from SecureController, which in turn derives from ControllerBase, which in turn derives from SmartDispatcherController. SmartDispatcherController is the main MonoRail controller class and all your controllers must derive from it (or its own base class, Castle.MonoRail.Framework.Controller, but that isn't as common). It's common for MonoRail applications to create their own ControllerBase derivation, similar to creating your own PageBase in traditional web forms. In this case, we also further derive a SecureController class which, as its name implies, allows you to secure access to any controllers that derive from it. How does SecureController restrict access to controllers? The class has the following attributes: [Filter(ExecuteEnum.BeforeAction, typeof(AuthenticationFilter), ExecutionOrder=1)]
This tells MonoRail that before any action can be performed on this controller, we need to first process a filter of type AuthenticationFilter. ExecutionOrder is helpful when more than one filter is applied to a controller, which isn't the case here.
Note that the controllers.config file contains an entry for our AuthenticationFilter class. While the above attribute indicates that we have to use a class of type AuthenticationFilter for the filter, it doesn't say which class specifically needs to process the request. This is another example of how MonoRail uses Windsor, the IoC container. By registering AuthenticationFilter in the controllers.config file, we tell MonoRail "if you need a class of type AuthenticationFilter somewhere and one hasn't been specifically requested, use this one".
OK, fine, so how does *AuthenticationFilter* restrict access to controllers then?
I'm not sure I like your tone, kiddo. Maybe I should just leave you to figure this out on your own, yesno?
No, no, no. I didn't mean it like that. I apologize. Please continue.
That's better. AuthenticationFilter (which derives from MonoRail's Filter class) overrides OnBeforeAction. This code will be executed before any action is performed on a controller that uses this filter. And there isn't anything particularly MonoRail-ish in this code. It checks to see if users are logged in using plain old System.Web.Security.FormsAuthentication. If they aren't, they are redirected to the login page. Or rather, they are redirected to the Index action of the Login controller.
If they are authenticated, OnBeforeAction returns true, which means the request will filter through to the originally requested action (in our case, the Index action on the Home controller). The last line of OnBeforeAction says "return false". The code never makes it this far because it either returns true or redirects to the login page before it gets here. But if it did get to this line and returned false, this tells the controller using this filter that it didn't "pass the test". The controller will then display a blank page which you can verify by commenting out both SendToLoginPage lines.
Summary
Two posts and we still haven't actually rendered anything yet. Yeah, well, security has a tendency of grinding everything to a halt. Here we discussed:
- Applying filters to controllers to execute code before an action is processed
- Deriving your own controller hierarchy
- Using Windsor again to provide a class when one isn't specifically requested
- Being polite to the hillbilly
Next up: We'll finally look at some rendered code and, with luck, what happens when you do something on the page.
Kyle the Insecure
Saturday, October 27, 2007
To do list for the day: - Catch up with the latest posts to altnetconf group
- Check my RSS feeds for new posts
- Read the four new posts from Ayende that have arisen since I started step 2
- Go to bathroom <optional>
- Repeat ad infinitum
In light of this new schedule, I'm afraid I'm going to have to ask all of you bloggers and ALT.NET contributors out there to preface your posts and e-mails accordingly with "Relevant to Kyle" or "Not relevant to Kyle" from now on. Try to err on the side of my lack of sleep. Kyle the Overwhelmed
Friday, October 26, 2007
I've mentioned before that we are blessed with a very accommodating customer where I currently collect a paycheque. He interacts with the team a minimum of once a day at our daily stand-ups and attends almost every other meeting we ask him to. And he has the power to make decisions, most of which are made on the spot (which is sometimes bad, but for the most part good). But sometimes I feel like we take his time and contribution for granted. We're all very appreciative and polite to him but on a couple of occasions I've sensed a bit of frustration on his part. Not with our progress which has been pretty good. More with little one-off conversations. Like the way we'll try to nail him down on priorities when he has other things he feels are more important. Or how we'll ask him a question and not offer guidance or suggestions on how things are done in other applications. I can't point to any specific instances of this because my memory sucks when it comes to things I don't feel I need to remember. And I should mention that I believe our relationship with him as a team is nothing short of stellar. I'm just left with some vague impression that, in a couple of instances, he was uncomfortable with something but wasn't quite sure what it was or whether he should bring it up. My guess is, we could be asking him, "how do you think things are going in general?" more often. And not at a sprint review meeting in front of the entire team. Just one person from the development team walking with him to the elevator after the daily stand-up to talk with him on a more subjective level. Or someone inviting him to coffee in the afternoon every two or three weeks just to see if there are any pain points he's feeling off the record. It would also give us a chance to show appreciation for his efforts. He is, after all, paying for us to play with some cool, bloggable technology. I'm not going to go into a whole spiel on relationships with your client. If you're the type of person I think/assume/expect you are, you know better than to take your client for granted. But the moral is: be nice to your customer. Within reason and within your own situation's context, of course. Not every customer will be so cooperative and/or available. If you are heading for the comments button to recount stories about your own Franken-client, make sure you can honestly say you've tried your best to make him or her happy first. And I don't just mean with the software you've built. Kyle the Sentimental
Thursday, October 25, 2007
And here we have, three common ASP.NET AJAX mistakes.
I haven't been out Ajaxin' that much lately but reading through that list surfaced some painful, painful memories. And I've dealt with Rogers Wireless Customer Service so I know a thing or two about pain.
The underlying thought that went through my head for each and every one of these mistakes is: Why is the technology so complicated as to allow these mistakes in the first place?
Look at the recommended practices to avoid the mistakes: Litter your code with checks for IsPostBack or IsInAsyncPostBack. Make sure you call events in the right order. And for heaven's sake, put that code in PreRender, not Load. Dummy. And my favorite from the intro: "this...means that using the UpdatePanel requires careful attention to the ASP.NET Page Life Cycle."
Now I don't want to be a hippo-critter-cal hillbilly. I did, at one point, live and breathe the page life cycle and saw no never mind to it at the time. But it's interesting how the introduction of alternatives can change one's perspective. Nowadays, I look back at when I dealt with OnInit, OnLoad, OnPreRender, OnRender and wonder if I sounded like some crazed Santa Claus when I talked to other people about it.
Kyle the Commonly Mistaken
Wednesday, October 24, 2007
Breaking form here by making someone else's link the sole topic of this post without adding anything other than kudos. But it's a really good link and it plays to my technical and musical leanings.
Props to Carl Franklin for a very impressive rendition of Home At Last (via Scott Hanselman). All four instruments *and* vocals (one can only assume he's doing backing vocals himself as well). Puts my own little flirtation with mixing from a few years ago, in the form of quotes from Glengarry Glen Ross intermingled with Pink Floyd's Money (sometimes very badly), into perspective. (Note: if you've seen the movie, you already know this but for those who haven't, that "flirtation" link is probably not safe for work. Carl's is.)
And yes, an e-mail has been sent to Carl to audition for Hillbilly Idol.
Kyle the Scouting
Tuesday, October 23, 2007
I'm having some trouble keeping up with the ALT.NET discussion group. The volume is one thing but the main impediment I have is that the level of discussion is ever-so-slightly out of my reach a good part of the time. At least when the topic turns technical. And with this group, it very often does. This in and of itself isn't a bad thing. I kind of like the challenge, especially when the topics are interesting and relevant. I think I'm about 90% of the way there in understanding the thread on validation spheres but it's taken more than one read-through (and I'll leave the actual number to your imagination). The problem I'm trying to come to grips with is a psychological one. This is a very open-minded and welcoming group of people. And yet I can't shake this feeling that I have to tread very lightly whenever I post a response. Like I need to walk this thin line 'twixt asking an intelligent question and sounding like I'm fresh off the boat (which, in some ways, I am and always will be). No one has given me any reason to feel this way. At least not explicitly. I have no doubt that if I posted the question, "What exactly is TDD?", the rudest response I would get would be several people glossing over the post without giving it a second glance. I guess it's more in the way they throw out terms as if they are common knowledge. Or in the assumptions that are made about my base knowledge. I have a feeling there are plenty of people on the list that feel the same way. The silent "unworthy" masses that are happy to follow along grasping what knowledge they can from discussions on lookup tables vs. enums, the same way I do. It's because of this feeling that I try to be somewhat self-deprecating in conversation and on this here blog thingy. I find people who don't take themselves too seriously more approachable and hillbillies do so like to be approached. In fact, this post is probably an extension of that. And this is not to suggest that anyone should dumb down their conversation. That's kind of the point of ALT.NET. It's *my* responsibility to get up to speed to a point where I'm confident enough to argue coherently with the more prolific contributors. But at this point, I'm still trying to sweat out the two posts I made last week. And in direct response to Scott Bellware, no less. Kyle the Phobic
Saturday, October 20, 2007
In my latest effort to pad out my posting count, I'm going to take a sample MonoRail application and annotate it. The reason being: I would have liked one myself. Yes, I can download samples and try to grok it by flipping back and forth 'twixt code and the API Reference Manual. But when I'm looking at a sample app, there are a lot of times I ask "why are you doing it this way?". And there are times where I just plain don't feel like slogging through documentation looking for the section that applies to a specific piece of code. That's about all I'm going to do by way of explanation because this will probably be a long enough post as it is. The sample app I'm going with is the Timok Portal Project prepared by the Castle folks themselves. I considered also the source code for the ALT.NET conference website (or at least a version of it) but frankly, I'm a little scared to say ALT.NET these days for fear that the Pedantic Police will take me away. This little adventure will assume little knowledge of MonoRail other than what it does conceptually. It also assumes you are familiar with traditional web forms and trying to map this new world into what you know. It's laid out as if you are first opening the app and trying to navigate your way through the flow starting from default.aspx. So I will jump around from topic to topic but it's meant to answer questions as they would theoretically occur chronologically. Whenever there are no references to explicit explanations, it is essentially my understanding of how things work. So take it as such. So without further adieu, we'll see how far we get today... Default.aspx Your standard MonoRail default page. It does nothing other than redirect you to the "real" main page: /home/index.rails. It exists because very likely, the IIS directory is configured so that default.aspx is the default page. OK, so let's take a look at index.rails. Waitaminute... It doesn't exist. And in fact, you may also be looking for a home directory off the root. Stop thinking of things in terms of files and directories. If you look in the web.config, there is a section called <httpHandlers>. The first one in the list says that any time ASP.NET finds a URL request that ends in .rails (excluding the query string), process that request with the MonoRailHttpHandlerFactory. That factory parses the URL and decides what to do with the request based on what it finds. And 99% of the time, that *doesn't* involve navigating to and processing an aspx file. To continue from default.aspx, the page redirects you to /home/index.rails. In MonoRail-speak, this means: Find the controller for "home" and process it using "index" as the action to perform. How does it know where the home controller is? Back to web.config. The <castle> section lists references to a bunch of other config files. One of these is controllers.config, which lists all the controllers used in the application. The one we are interested in is home.controller, which refers you to the HomeController class in the web project. How does it know to look at the "home.controller" element? Through the magic of convention and the Windsor IoC container. If you're not familiar with Windsor or IoC, think of it as a way of helping the application to find things it needs when they aren't explicitly provided to it. In this case, Windsor is helping the application to find which class to use when we request the home controller. In this case, it's HomeController.cs in the Controllers folder of the web app, as can be seen from the home.controller component. So where's the HTML that HomeController renders? It may not seem obvious but there are other files associated with this class, similar to how an aspx file is associated with its code-behind/code-beside file. The controller has two attributes attached to it: Layout("default") and Rescue("generalerror"). The Layout attribute tells us which layout to use when rendering the page. Layouts are stored in the layouts folder in the web project. This is always where MonoRail looks for layouts which is why there is no explicit link to the folder from the controller. Layouts are analogous to master pages and I'll leave it at that for now. If you open the layouts folder, there is only one layout: default.vm. Coincidentally, the same name as was used in the Layout attribute of the home controller. (Note: It's not really a coincidence.) So at this point, we have the controller telling us which layout to use to render the page template. Default.vm contains mostly HTML with some "other stuff" thrown in. The only "other stuff" I'm interested in at the moment is $childContent, which is analogous to the PlaceHolder ASP.NET server control in a master page. This is where the individual content goes for each controller that uses this layout. The HTML that goes into that placeholder is located under the Views folder in the web project. Specifically, it is in Views/Home/index.vm. Again, there is no direct link telling the controller to go to this file specifically. Rather, Monorail will look under the Views folder for a subfolder matching the name of the controller. And also note that the name of the file, index.vm, matches the name in the URL we are requesting: index.rails. Minus the extensions. Again, not a coincidence. One final note on the controller. It contains a method called Index which, by this time, should give you some indication that it is important with our request for index.rails. This method will be executed before the index.vm view is rendered. And again, nowhere does it explicitly say, "if you are requesting index.rails, execute the Index method in HomeController". The underlying link in all of this is just the name of the request: index. Summary In our request for /home/index.rails, the following actions were taken: - The request was routed to MonoRailHttpHandlerFactory because it ended in .rails
- The factory parsed the URL to determine which controller should be used to render the request. Using the Windsor container, it determined that we should use HomeController to render the request
- HomeController executed the Index() method, loaded the default.vm layout, and inserted the index.vm view into it and rendered the result.
One of the underlying themes you may have seen is the reliance on "convention over configuration". MonoRail knows where to find things because of the conventions used. Views are stored in the views folder, layouts in the layouts folder. The Index method is executed because we are responding to the index.rails request. Compare this with an aspx page where there is an explicit link 'twixt it and it's underlying code-behind file (via the Inherits attribute on the <@Page@> directive). This is (hopefully) the first in a series because, quite frankly, we haven't covered much yet. Next time, we'll continue where we left off, which is with the index.vm view. But before that, we'll need to talk about why, when you launch the application, you are actually first re-directed to the login page. Kyle the Derailed
Friday, October 19, 2007
After rambling on landing remote contracts, pairing over the wire, and working remotely, this will likely be the last little meandering on the topic for a while. Don't wanna get typecast. This is kind of an extension on working remotely. It focuses specifically on attending meetings (i.e. teleconferences). We have quite a few where I am, at least one a day in the form of our daily stand-up. And the rest of them are almost as intense in that I'm generally required to stay alert and avoid zoning out. They are usually very developer focused. Design sessions, sprint planning, feature reviews, and even impromptu discussions on specific pieces of code. First and foremost: Get a decent phone. At a minimum, one with speakerphone and a mute button (for meetings that coincide with when the young'uns get home from school and yell, "DADDY! I STEPPED IN SOMETHING ON THE WAY HOME FROM SCHOOL!"). A portable handset is also nice to have. It should also have speakerphone and a mute button but make sure the phone still works while it is charging in the cradle. My current phone does not so when the battery is dead (which happens more often than you think in a paired environment), I'm either unreachable by phone or scrambling for a couple of tin cans and some string. Also, get one with a decent range. One that still works through two floors of concrete, which mine also does not. For meetings where I don't have to physically be at a computer, I tend to walk around a lot. I could pretend that I do it to help keep my creativity up but frankly, I just like to be on my feet. Skype is probably a viable alternative to a phone but I haven't used it for work. In any case, if you do consider it, keep in mind the speakerphone, mute, and mobility factors mentioned above. I'm guessing there are devices with those features that work over Skype but again, I know not of these. And if you are working several time zones away (and especially in a different country), consider getting a Vonage account with a number local to where you typically get your contracts. This may involve some surreptitiousness when signing up for your account depending on the availability of Vonage in your area but if you are in North America, you shouldn't have a problem. (Side note: If you buy a router with VoIP jacks in the US, it doesn't work out of the box with Vonage Canada. You need to call them to get them to, I dunno, enter it in a spreadsheet or something.) That's enough on phones. Here's what to do when you're in the meeting. Pay attention There will be huge urge to multi-task. To finish up that last bug while everyone else is scrummin'. To complete that last level of Halo 3 during the opening banter of a design session. Avoid this. Especially for meetings where you are expected to actively contribute. It will often be the case that there is "dead time". As in time that you don't need to contribute but you still kinda need to pay attention. And without anyone there to nudge you, it's nigh impossible to keep from zoning out at best and outright falling asleep at worst (again, consider a phone with a mute button). For these meetings, get a scratch pad. Not the one you use to take important notes. More like a doodle pad. And go nuts. Nothing intricate. Just enough to keep your brain from dozing off while still keeping focused on the meeting. My current MO is actually to write down what people are saying. Not as a means of taking notes but more of a reinforcement of what's being said. Kind of a memory aid, I guess. You don't even need to make them complete (or even coherent) sentences. Just random words that jump out from the conversation. Don't be shy It's very easy for people to forget you're there. Don't be afraid to tell people to speak up if you feel you're missing something. Ignore the previous two tips when appropriate There will be meetings where you can let your consciousness slip in and out at will. In these cases, I see no harm in getting some work done while keeping an ear on the proceedings. Use your judgement and err on the side of caution. And practice some generic phrases for when someone blindsides you with a, "What do *you* think, Coding Hillbilly?" Some that have served me well: - Yeah, I'm good with that
- I dunno, have we considered every angle?
- Well, I'm a little worried about...actually, never mind. Yeah, that'll be fine.
- Sorry, I was watching Oprah
- I've given this a lot of thought and I think we should--<click>
And so on and so forth. Keep in mind that these meetings should be atypical. And in my experience, you don't need to hide the fact that you are only at 50% capacity for these meetings. This will depend on the group you're in but generally speaking, if your tech lead knows you multi-task on occasion, he or she will get a sense at which meetings you're doing it. They will be the same ones he or she would do the same given the opportunity. Bring in a group in IM IM is your friend, embrace it. There are many times when you would typically wander in to another developer's office and start talking about a piece of code. Then you call out to another one to get another perspective. Then another and another until you start violating fire codes. We've been having some reasonable success replicating this with IM by adding more and more people to conversations in what are essentially break-out sessions for a very specific purpose. It ain't the same as being there but it's a decent substitute. I believe I have sufficiently steamrolled the "working remotely" horse for the time being. It's been fun padding out October's post count but methinks it's time to get back on track. Kyle the Diversionary
Wednesday, October 17, 2007
Another entry in what one might think was a planned series of posts on working remotely. Previously, I've discussed how to land contracts and some remote pairing tools. Today are some general tips on what to do once you've got the contract. As with the rest of this blog, these points have helped me retain some small shred of sanity. If they help you out too, that's not my fault. I'll start off with some regurgitation of two points you've likely read elsewhere but I won't dwell on them too much. Firstly, set up a proper office space separate from everything else and treat it as such. Helps the disconnect 'twixt work and home. Secondly, get ready for work as if you were actually going. That generally means taking a shower in the morning at the very least. It's surprising how big a difference this makes for your frame of mind. Makes you feel like you are actually working and not just still awake from playing World of Warcraft all night. If you remember one thing about this post, it's this: Cook 'em with the skin still on. But almost as important: Be productive. And when you can't be productive, be *very* productive. In the post on landing contracts, I touched on this a little. Many places will be apprehensive about the idea of a contractor working offsite...in a tropical paradise....with a beach so close....and such...nice weather....could just....step out....just for a second. Whoa Hillbilly! Focus, you big hunk of Appalachian American! The point is that there may be the expectation that you aren't working to full capacity. There are lots of distractions at home and no one watching you and they know it. And while it's no different than zoning out at work and ego surfing, it will look worse if you do it. So you will need to shatter their expectations in terms of your madd skillz simply to justify your expense. If you consider that unfair, you could always commute. Follow-up point, if you have to leave your home for *any* reason, mark it in your calendar and send an e-mail to some key team members. Nothing shatters confidence like someone calling you in the middle of the workday and getting your answering machine. Next up is your work schedule. I am two time zones from my mother ship. The core hours are 8:30 to 4:00 which translate to 10:30 to 6:00 my time. And I'm a morning person. You will need to show some flexibility here but you don't need to go overboard. Here's where being productive can work to your advantage. At my present gig, no one has overtly questioned me stopping work at 3:00 local time but at the same time, I don't decline meetings that run until 6:00 my time either. Your goal is to make your remoteness as seamless as possible and not to be an impediment logistically if you can help it. Besides, they are always nice enough to ask if it's okay to schedule a meeting that late and typically, I don't need to be at my computer for it. Related to this: you may need to adjust when you take your lunch to more closely match the lunch hour of your employer. Assuming you are two time zones away or less. Any more than that, I think it's probably impractical. Where I am now, we practice agile in some form (although sometimes, we are accused of merely being spry). Our scrum wall is the "master catalogue" of our current issues and bugs. Which isn't the most efficient way of tracking for me. Of course, we also have a technology solution (Team Foundation Server. Oh stop it, it's not that bad.) that wasn't quite as up-to-date as the wall. But it is now. Because it *is* my scrum wall. If your team also makes use of lo-tech for its process, you will need to use, and enforce the use of, the underlying technology to keep yourself up-to-date. Finally, if you do work onsite at the beginning, test your remote access before you fly home. Sorry, I don't have any horror stories to demonstrate why this is a good idea because I've always done it. But if you like, I could make one up that involves being on the phone with the help desk for two hours, shipping a laptop internationally, and having it arrive damaged. Still one more post to go on "attending" meetings remotely (who knew it was big enough for its own entry?). ** UPDATE ** As the hillbilly recovers from a night of debauchery and questionable antics, he is reminded the he failed to mention some of the more obvious benefits of working from home in a time zone two hours later from his home base
Kyle the Recoverable
Tuesday, October 16, 2007
On the heels on my post on remote pairing, I had a quick look at Microsoft SharedView Beta2 yesterday. I say "quick" look because that was all it took to determine I wasn't going to be using it for remote pairing. The majority of this post is why it's not going to work for me. In order to start using SharedView, one person has to create a session, then invite the other via e-mail. The other person joins the session by entering in the session name and session code (randomly generated). There are hints that this may be easier if you have a Windows Live account but I never got that far. Next, you can share exactly one application at a time, or your entire desktop. So no sharing Visual Studio and the console window. But to be fair, when I pair with someone, I generally share the desktop anyway. (Related to that is an issue I forgot to mention in the remote pairing post: Alt+Tab, or lack of it). When you do share an application, everything else (and I do mean *everything*) goes gray. Not disabled mind you, just gray: The apps behind the console are still active, though it isn't very obvious. And it does make for an interesting user experience dealing with muted windows. On the other end, if you are the sharee, the application being shared is squished into the available size of your screen. Even if your resolutions match, the app is shrunk a bit to allow for the SharedView toolbar and some padding to make for good gestalt. Compare this with Office Communicator where the app remains the original size but the window scrolls if it doesn't fit your screen. If I had to choose 'twixt the two methods, I prefer the Office Communicator version. The one advantage I found over Office Communicator's application sharing is that I can actually share something over remote desktop. But frankly, as long as someone else can share their desktop, I don't much care whose desktop I deal with. This isn't an extensive review by any means. In fact, it barely qualifies as a cursory one given that I spent all of about six minutes evaluating the product. But it was long enough to determine that SharedView was not designed for remote pairing. Looks great if you want to give a presentation to a group of people. It does allow you to see the other attendees' mouse pointers which I imagine could be useful if they have a quick question about something on the screen. The performance was adequate if a little chunky though to be fair, there were at least two other communication protocols 'twixt me and my guinea pig. For now, I'm not feeling enough pain with Office Communicator to put my potential pairers through another install process. But if the opportunity comes up, I'll probably give Yugma or TightVNC a try based on their prices. Kyle the Shared
Monday, October 15, 2007
Tried to respond to Chinh Do's comment on a previous post this morning and lo! the Coding Hillbilly has been dubbed a social networking site by his employer. And Jayzus knows we don't want workers who network socially (unless it's for the United Way judging from the amount of ad space it gets on the company portal).
Interestingly, the sister-aunt site to this one is still deemed acceptable viewing.
Anyway, I'm glad my employer has shown me the error of my ways. I was almost unproductive there for a second.
And yes, this post was written during normal work hours.
Kyle the Spiteful
Sunday, October 14, 2007
Some great discussions going on in the ALT.NET user group. Topics such as BDD, ReSharper/CodeRush on large projects, and one that hits close to home: Remote Pairing. I felt some trepidation when I left Calgary to come work remotely from home. There is a *lot* of interaction 'twixt developers, including daily stand-ups, lunch 'n learns, design sessions, afternoon kickboxing, sprint reviews, and, of course, pairing. Ditto for the client who shows up every morning for our daily stand-ups and every sprint review and sprint planning session (no, seriously). So I was somewhat apprehensive about making it work remotely. But three weeks in, I'm having some reasonable success with Office Communicator and a Vonage account. Office Communicator for the application sharing and Vonage so I don't have to keep switching back and forth to the IM window. (Side note: I've noticed Vonage has been a lot more reliable in recent weeks than when I first got the account.) I say "reasonable" success because there are a couple of issues. Firstly, the last time I paired (two days ago), the connection dropped several times. As in at least half a dozen until we gave up entirely and my partner went off to pair with someone a little less virtual. This is the only time it's happened and I'm not sure what caused it as I didn't lose the internet connection. Issue number two: Apparently, Application Sharing doesn't work if you are connected via Remote Desktop or Citrix. Which means it sure as heckfire ain't working if you connect via Remote Desktop through Citrix. It works if someone on the other end shares Visual Studio with me but I can't do it myself. But those glitches aside, remote pairing isn't much different than local pairing. One of us would write the test, the other would make it pass and it isn't all that from removed from actually being there. In fact, it helped reduce the "here, let me drive for a sec" factor. The next tool on my list to try out is Microsoft SharedView Beta. Here is the link where I got it but it's also listed in a couple of other places that look valid (as well as one other place where the links don't work at all). No idea whether it will solve my issues but it was recommended to me by someone at Microsoft and I don't do nothin' until the Mother Ship tells me to. To tie this back to the ALT.NET discussion, here are some other combinations along with the people who talked about (but didn't necessarily recommend) them: So there is no shortage of options although only the Skype/Yugma option came back with a glowing review. Everything else was "pretty well" or "well enough". Kyle the Re-paired
Sunday, October 14, 2007
The conversations on changing the name of ALT.NET have (thankfully) died down and I don't want to resurrect them in the mailing list which is why I'm posting this here, tongue firmly in cheek. I just realized I've had the perfect name all along in my category list: Conscientious Coding. The underlying tenet from the original post (and let's ignore the misguided critique on TDD, shall we. So young was I in mid-2006): Someone else is going to have to deal with your &*%$ after you leave. Be nice to them. Kyle the Affable
Saturday, October 13, 2007
Strolling through some Visual Studio tips courtesy of Chinh Do. Some good tips although some go away with ReSharper (and we won't get into the part in Tip 4 where he says "Regions [are] a great way to organize your code". For now, I'll focus on Tip 6: "Attach to Process" to Start Debugging in ASP.NET. A quick summary: If you already have the application running in a browser, you can "attach to process" rather than pressing F5 to compile and run the app. The idea being that you don't need to launch your application and navigate to where you need to be. Here's my own preferred method which goes along the same lines. Like Chinh, I launch the application in its own browser. (Side note: Usually this means creating a separate virtual directory for it in IIS but if you want to use the built-in web server (Cassini it's called, yesno?), you will have to launch the app from Visual Studio at least once to start the web server.)The next step is creating an empty html page and setting it as the startup page. That's pretty much it. With this setup, you can play around with your code, re-compile (Ctrl+Shift+B), then refresh the browser to see the changes. Like Chinh's tip, there is no need to press F5 to launch the app, then navigate to the page to see your changes. And you can still debug in this method. That's what the blank startup page is for. Launching the app will attach the debug process to your existing browser instance (as well as the instance that is launched when you press F5). So if I do need to step through code on a page, I can set a breakpoint, press F5 to attach the debug process, flip over to my existing browser and refresh the page to hit the breakpoint. The blank startup page serves essentially as a launching pad. The advantages are pretty much the same as in Chinh's original tip. With my method, it's easier to attach to the debugger because all I need to do is press F5, rather than Alt+D, P, "as", Enter (which, truth be told, is still pretty quick). With his method, you manually stop debugging (Shift+F5). With mine, you can still do that or you can close the startup page to do the same thing (at least in IE, Firefox doesn't do the same thing). Having said that, Chinh's method has one serious advantage over mine (and over debugging with Visual Studio using F5 in general): It doesn't matter which browser you use. If you want to use Firefox, you don't need to muck with Visual Studio to set it as your default browser. You can launch your application in both browsers, attach the aspnet_wp process, and refresh either one (or both) and your breakpoints will be hit. So with that advantage in mind, along with some other minor quirks in my method, I'll be switching over to his "Attach to Process" for the time being to see if it makes things easier. Kyle the Detached
Friday, October 12, 2007
Holiday in the Bahamas today but not in Canada. Which means I'm working while my daughter plays XBox behind me. So I'm going to vent my frustration on #regions. Maybe it's my alternative upbringing but I'm not a huge fan of #regions in Visual Studio. And here is one example why: As-is, this is pretty useless to me. My first order of action when I see this is Ctrl+M, then Ctrl+L to expand the entire thing which is another step I need to do to get my work done. "But Coding Hillbilly," you say, "doesn't it help to organize your code?" NAY, I say, NAY! If you are looking through a piece of code and see a method or property belonging to the Raccoon class, how do you go about looking for it? Do you analyze whether it is a property or method, then search for the class in Solution Explorer, then epxand the corresponding region and scroll through it? Of course not, you press Ctrl+B to zero in on it with ReSharper (and I'm pretty sure Visual Studio has a semi-functional alternative). The point is, you couldn't care less where the method is in the code. There are better ways to find methods. Ctrl+B, Ctrl+Alt+B, Alt+F7, Ctrl+Shift+F, Ctrl+F12, even skipping through the methods using Alt+Up and Alt+Down. In fact, I would argue that separating them into #regions like this actually makes it harder to scan through code because of the cases where some regions are expanded and others aren't. Using ReSharper also exacerbates this problem. A common refactoring scenario is Extract to Method (Ctrl+Alt+M, if memory serves). And ReSharper isn't going to bother searching through #regions to figure out where the method should be placed (nor should it). Ditto for when I start using method names that don't exist, then Alt+Enter my way through some NotImplementedException goodness. The #regions just get in my way. I've also been in places that are so dogmatic about them, there are actually empty #regions because the coding standard says you *have* to have one for private methods, even if you don't have any. And don't get me started on nested #regions. Admittedly, they do have their place. Prior to .NET 2.0, it was nice having the designer code hidden from view. Ditto for when you implement trivial interfaces that you rarely want to look at again. IConvertible, for example. So I suppose the real point is, don't overuse them. You aren't organizing anything by compartmentalizing properties and methods in this way. If you're one of those compulsive types, write some sort of add-in that alphabetizes the members or organizes them by how long they are or something. Just don't dump them into #regions. Kyle the Regional
Friday, October 12, 2007
The image to the right is what greeted me after strolling through the ALT.NET participants list and updating my OPML list. And this is after reading posts all morning. Damn you, ALT.NET, for making me think! Kyle the Immort
Thursday, October 11, 2007
With the winter months approaching the motherland, it's probably time to remind my readership, respectfully, that I live in the Bahamas and you don't. Of course, there's always a chance that you are also a .NET developer living down here. To which I reply, "I've been looking for you everywhere! Where the &*%$ are you?!?" For the rest of you, forgive me if I sounded boastful. I meant to, but forgive me anyway. It was necessary to set up this post. Two questions were asked of me recently: - Is there a lot of work on the islands?
- How are you able to land contracts working remotely?
The first question is easy: no. The Bahamas is an island of about 300,000. That wouldn't even qualify it for the list of the top fifty most populous cities in the United States and places it sixteenth on a similar list for Canada, behind London, ON and Laval, QU. And the IT industry kind of runs counter to what the government generally likes to promote to other countries. Hard to reconcile "Hotbed for mobile device development" with those Corona commercials showing people skipping Blackberries into the ocean.  Working remotely also requires at least one crazy powerful wireless router Another problem is that the very few development shops that do exist have, shall we say, "skewed" expectations when it comes to value per dollar spent. There's still very much a "two junior developers can do just as much as one senior developer" mentality that, to date, I haven't worked up the effort to fight yet. The reason I haven't taken up the cause leads to the second question. I have been reasonably successful in landing remote contracts in recent years. But I'd be lying if I said it was easy at the beginning, and even now to some extent. In the four and a half years I've lived in the Bahamas, I've spent a total of eighteen months away for work, including twelve months in the first two years alone. And the rest of that time included an eight-month stint as an employee for a local company. Since moving here, I've worked on about half a dozen or so contracts and exactly one of them was entirely remote. As in: they didn't need me onsite at the beginning, middle, or the end. And for that one, I was subcontracting for another contractor who actually *was* on-site and managing the project. The rest of them, in some form or another, required me to be on-site for all or part of the contract. In my experience, companies like to see their contractors, especially senior ones and especially senior ones that live in the Caribbean. Unless you go in to a place where you are a known commodity or strongly recommended, many places want you on-site at least at the beginning, if only to prove your mettle. For the last two years, I've been contracting for companies in Calgary because that's kind of my home base in Canada. I know quite a few people which is how I've been able to land the work. In all cases (three to-date), I've given a hard end date as to when I was heading home. I think it's important to do that because there is no "well, we assumed you'd be staying longer". Be very clear to all involved that you will be leaving by a certain date up front. And if they balk, treat it like a rate negotiation. I.E. If you really want the contract and don't mind staying longer, offer to stay a little longer. If you are keen to get home, tell them you're leaving by that date whether you're working for them or not (but say it a little less crassly). Few will complain if you say you don't want to be away from your family that long. Like I said, if you're up front up front, there will be less pain in the future. In one case, I started the contract not knowing if they would even extend it past the date I said I was leaving. That requires a bit of a leap of faith and more than a little confidence in yourself. When it came near the end of the contract and they asked me to stay, I said I'd love to but that I was very clear that I had to leave by the date I gave them and if you'd like me to continue on, I'll need VPN access so I can work from home. That one had the advantage in that staying any longer would have had tax implications so there was even less flexibility involved. The Hillbilly pays tax for no man, woman, or company. As I mentioned, all the remote contracts I've landed have been through people I've known. And I can not stress enough the importance of that kind of networking when you want to pull this off. People are far more likely to assume you're not playing XBox all day if they are familiar with you and, more importantly, your work. My current contract was landed through an e-mail blast to my address book when someone responded with "Come work for me, biatch". You don't get that kind of personal service from an agency. So make yourself known. Blog, attend conferences, go to user groups, *speak* at user groups. That's what is currently working for me. It also helps to be ridiculously good-looking or irritatingly handsome (oh wait, which blog am I writing today?) Final comment: I didn't set out to do what I do. It came about through necessity. My wife's work moved her down here and I tagged along. And given the answer to the first question above, I had to learn to adapt pretty quickly. Not everything worked and my career is still a work-in-progress (and I kind of hope it remains that way until I retire). You'll encounter your own challenges and have different success factors. Flexibility will be key at the beginning. There are some tips to use when you actually do find a contract working remotely. And when I say "remotely", I mean a situation where you can't "pop in" for the occasional meeting. I mean you are working in a different time zone. But I'll save those for another post 'cause the Hillbilly appears to have run on a bit. Kyle the Beached
Thursday, October 11, 2007
Well, joining the ALT.NET movement has certainly honed my inbox management skills. Thank Allah for GMail's conversation grouping feature. Some good and irrelevant stuff being discussed in the user groups ("good" and "irrelevant" being subjective terms in keeping with the nature of the group). My own reaction has been mostly in line with Master Simser's which has also been espoused by more than a few people. That is, I've reached out to three user groups I've never spoken at before to offer my own brand of down-home, folksy advice as it pertains to software development. I'm already starting to scan, rather than read, the e-mail exchanges which are focused on the group's identity. Not sure why people are so hung up on it, especially since we've got all of one conference under our belt. But if everyone was as passive as I am, I suppose there wouldn't have been a conference in the first place. In any case, that's not what I came here to jaw about. Much has already been said on Microsoft/Scott Guthrie's MVC framework. And during the conference, more than one person asked, "what does this mean for Monorail"? The fine folks of Castle apparently have been asked this question as well because when I wandered over to their website (looking for Monorail documentation), I found a nice little reaction specifically to that question. And it was one that I expected them to make: choice is a good thing and we'll be looking at how to integrate it with the rest of our products. 'Tis a good time to be a software developer. Jay the Schizophrenic
Sunday, October 07, 2007
Bah! I sit down to summarize today's sessions and instead I'm staring, one eyebrow raised, at a pissing contest in the form of a string of posts slamming alt.net and others defending it. I'll let you Google the details partly because I don't want to call out anyone individually but mostly because I don't want to give anyone the press on it. Because this issue doesn't deserve any*. Some of these posts were so inane, I had to add the authors to my blogroll so that I could have the satisfaction of removing them. All I want to do is write decent software. That's why I came. To meet people who have been espousing techniques I've been trying to learn for the last few months and pick their brains. I liked some of what I heard and didn't like other stuff. Maybe I'm overly optimistic, but can't we just stop bitching and assume people are smart enough to figure out for themselves who they want to read and how they should build software? I get enough of the "Janie said I was stupid" attitude from my eight-year-old. That's enough of that &*%$. Here's what I did today: How to get the word to the street This was essentially a talk on how to promote some of the techniques that lead to good software design. How do you encourage other developers and managers that there is value in TDD or DDD, for example? (I.E.: "how to force other people to do what I do" **). There was an emphasis on how Microsoft and MSDN Magazine could play a role in this and the two main representatives in this area, Howard Dierking and Simon Guest were very receptive. There was very much a "we know some good alternatives, how do we let other people in on it?" vibe. Language-oriented programming Didn't realize this would be on DSLs but I guess I should have. It started slow with people harping on what I felt were irrelevant topics but Scott bludgeoned people back on to the right track. Wrap-up We all said a few words (some more than others) about what we got out of the conference. Then we held hands, sang Kum-Bah-Ya, and prepared for ascension to the heavens to meet our alien ancestors***. The name of the group was debated to the bitter end and since you all asked, here's my opinion: I don't care. Consider the following and what relationship they have with what they are associated with: Sun, Java, Amazon, Civic, Oracle. The underlying meaning of the words behind the name will take a backseat to what the group actually accomplishes so don't dwell on it. Final thoughts: I had a blast. Yes, there was some clique-ishness, if, by clique-ish, you mean people recognized old friends and treated them as such. I never once felt excluded from any conversation or discussion and never once felt like I was being talked down to (and keep in mind, I can pinpoint to the day when I started learning this and it wasn't that long ago). The closest I came was when I interrupted Scott Hanselman while he was distracted with a connectivity issue and even then, he kept encouraging me to stick around and chat. Seriously, these are some crazy-friendly people. Now can I please go back to building software? Kyle the Parental * Yes, I'm being hypocritical. The Hillbilly works in mysterious ways. ** I'm kidding, get your mouse away from the Comments link. *** I'm kidding again. Geez, did they remove your sense of humour with your appendix?
Saturday, October 06, 2007
The first full day of sessions is over and I'm sorry to report there was not a single mention of moonshine, although by the end of Scott Guthrie's presentation on Microsoft's MVC, I sure felt like I'd had a few jugs. The Hillbilly doesn't do note-taking, but I seriously doubt there will be a lack of coverage on individual sessions given the audience. So you will have to be satisfied with my own little Appalachian-American take on the proceedings: Domain-Specific Languages This topic holds some interest for me academically but I doubt I'll see any real-world implementations of this in my immediate future. There were a lot of questions about what exactly constitutes DSLs, at least until Martin Fowler joined. And I must admit, he held himself well considering the inner turmoil he was going through. But his example domain, "Dealing with loss" was telling. Behaviour-Driven Design Hey, did you know that Scott Bellware likes BDD? Neither did I! Microsoft's MVC Framework Wow! This looks fine like a greased porky-pine. There was a *lot* to like about this presentation. It was nice to see that Scott Guthrie and his team looked at existing frameworks and didn't develop this in a silo. I'm sure there will be much talk on this subject by people more qualified and verbose than I so I'll leave it at that except to say the beta is expected in six to eight weeks. DDD Jujitsu A scrappy affair this one was with Dave Laribee and Scott Bellware (among others) sort of butting heads on how best to implement a model. The debate was whether a function like TransferFunds for an account should reside in the Account object or in a separate service. My instinct had me on the latter side but there were good arguments from both camps. After that was a quick wrap-up and judging from the comments from others, Microsoft still looms large with alt.netters. Much praise was given to Scott Guthrie for the new framework and when it was suggested that we shift focus from it, people simple commented on Microsoft in general. I did meet another healthy dose of developers. And in that vein, I'll close up with a "fill in the blank" quiz. Given the following last names, fill in the first names. HINT: All answers are one or more of: Chris, Dave, or Scott __________________ Laribee __________________ Hanselman __________________ Guthrie __________________ Woods __________________ Holmes __________________ Ortman __________________ Bellware __________________ O'Hara __________________ Patterson Kyle the Alternate
Saturday, October 06, 2007
First day of the ALT.NET
conference. I read the mantra for Open Spaces but didn't quite take it
seriously: Whoever shows up is the right group. Whatever happens is the only
thing that could have. Whenever it starts is the right time. When it's over,
it's over.
Sounds pretty zen, especially for Texas. In any case, it looks like it will
make for an interesting conference. And I'll be trying out these rules the next
time I get in trouble from the missus.
We started off with introductions and a little round table thingy where it
became clear that I have a different definition of "alternative" than others do.
I thought "alternative" implied the use of unconventional ideas or a choice
between two or more options. Seems there are a few people who took it to mean
"something better than what Microsoft feeds us". Hope that doesn't become a
prevalent theme because I'm more interested in getting tools for my arsenal than
discussing what's wrong with any particular technology.
We did manage to nail down some topics for discussion for the remaining two
days. Here is my agenda for tomorrow:
9:30 - 11:00 - Where is Justice Gray and why isn't he here?
11:00 - 12:30 - Who is Justice Gray really?
1:30 - 3:00 - Agile development as it pertains to Justice Gray's hair
3:00 - 4:30 - How can we make Justice Gray a better developer in six
months?
But despite at least one glaring omission, I've already met a lot of great
people and I'm looking forward to continuing the trend tomorrow. And if I happen
to learn something in the process, well, it'll still have been a successful
trip.
Kyle the Anticipatory
Monday, October 01, 2007
Why, I do, dear gatekeeper. And I can't think of any branch of software development more alternative than hillbilly development (as it were). Potential topics for discussion: - Backwoods-Driven Design
- The family tree problem: Is it really NP-complete?
- The open/closed principle as it applies to farm critters
- Mashups (aka Moonshine Development)
- Beauty
Lookin' forward to seein' all my software developin', system analyzin', enterprise architectin', red-green-refactorin', unit-testin', domain-driven cousins out yonder in Austin! The Hillbilly will be there repreSENtin'!
Monday, October 01, 2007
One of my contracts involves what is essentially a document management system where users can search for legal documents based on metadata attributes as well as their contents. I've been working on it since before the days of SharePoint and even before Content Management Server was somewhat affordable. I mention this to cut off any comments that might say, "Why don't you just use a document management system?" It's in .NET and could benefit from migration to another platform. I'm not going to do it for reasons not worth mentioning. ACCEPT IT! There are two things worth posting about. Neither are new techniques by any stretch. The first is how to search the content and tie that into the metadata search. The second is how to restrict access to the documents (all in Word format) which are not restricted by IIS by default. Searching In order to search the contents of the repository, I'm using a technique that's been around for many moons. It starts with Microsoft Indexing Services (right-click My Computer, select Manage..., and it's under Services). I created a catalog and added the directory containing my documents. Easy enough. Now I have a catalog you can query from code using the Indexing Service query provider. I'd give you sample code but I don't have any; I don't query the catalog from code. It's no good to me on its own. I need to merge the results in with the metadata search in SQL Server. And rather than get one set of results from SQL Server and another from Indexing Services and merging them, I'm letting SQL Server do everything. To do this, I added a linked server to SQL Server: EXEC sp_addlinkedserver MyDocs, 'Index Server', 'MSIDXS', '<Indexing Service Catalog Name>' The first parameter can be whatever name you want. The next two are fixed and the last is the name of the Indexing Service catalog. From here, you can query the results directly from SQL Server and join them with any other query you want. For example: SELECT MetadataField1, MetadataField2, DocumentFileName FROM doc_metadata dl INNER JOIN OpenQuery( MyDocs, 'SELECT Filename FROM SCOPE( ) WHERE CONTAINS( Contents, ''<search term>'' ) ') q ON dl.DocumentFileName = q.Filename WHERE <filter conditions> And just like that, that squirrel's done, as my pappy used to say. The Indexing Service includes a bunch of properties you can return if you like, but for my poor man's document management system, all I need it for is to filter the list of search results. NOTE: Out of the box, the Indexing Service will index all forms of Office documents. For anything else, you'll need to find an appropriate filter that plugs into the service. | |