| Michael's profileBrownie PointsBlogLists | Help |
Brownie PointsThe Tale of a .NET Conv...Fanatic. |
|||||
|
June 03 The “Green” MovementI know people feel the need to be environmentally conscious. I do as well. But let’s get past the BS. Very few companies are “Green” for the sake of being “Green”. IBM spelled it out nicely with their commercials, the CEO doesn’t want to hear about going “Green” until he realizes that it can impact his bottom line (going green means a savings on energy bills). I’m all for that! I’ve been a major proponent of leveraging virtualization at our office. in the hopes that I came back late Monday night (or early Tuesday morning depending on your view) from an extended weekend in Chicago -- well technically it wasn’t the weekend for me since I was still working to finish the final stretch of this pretty interesting project at the office – and noticed that the dumpster that is normally in the parking lot was gone. Thinking nothing of it I bundled the garbage that had accumulated in the rental car (it gets better mileage than the family car so I’m being “green”), placed it in the pen where the dumpster normally would be and proceeded to unpack the family and dump the girls in their respective beds. I get home from work and find a notice on my door from the management community saying that per a previous notice the dumpster behind our unit had been removed and we were to use a centralized community trash compactor. Any further “infractions” would be penalized by a fine. Mind you this centralized garbage drop off is a good five blocks away from my unit. So I call and ask them if they really expect me to carry my trash 5 blocks in order to get rid of it. “Well most people just put it in their car and drive it there.” I’m not even going to go into my reaction regarding the thought of putting garbage in my car to drive to their dumpster (like it’s laundry or something) Here’s the punch line. They had the nerve to say on the notice this was part of their “Green Initiative” in “reducing carbon footprints by having one site for the waste company to pickup from”. Really? You’re telling me that having 500+ Apartments load their car up with garbage and drive out of their way to dump it reduces the carbon footprint? Even IF it did, that’s not what I signed up for when I put my name on the lease. That’s tantamount to me looking at the apartment and seeing the Washer and Dryer in unit, signing the lease based on that and halfway through the lease, they take my Washer and Dryer away. By the way I feel sorry for the people who live in the units next to the central dump because it’s overflowing (grossly undersized for being the only dumpster in the entire FRIGGIN SUBDIVISION) and I’m sure it stinks and attracts rodents. But hey we’re April 06 Blend Behaviors FTWIn this post I talk about Blend Behaviors and how they can be leveraged to execute a command without any code-behind. March 20 Baking Up Another BatchMix ‘09 just ended today. Microsoft announced some amazing stuff there. I’ve got some samples I’m working on to share with you, I just didn’t have enough time to finish them for a zero-day release. What am I excited about from Mix? Silverlight 3 Silverlight 3 has a lot of features that make it compelling not only as a Flash alternative in web scenarios, but the new out of browser experience presents a good case for using Silverlight as your default client framework. And the cross platform capabilities are just the icing on the cake. There are more goodies to talk about with Silverlight 3 as well, like:
RIA Services I’m extremely excited about the scenarios enabled by the RIA Services Framework. RIA services acts as an application service layer between your UI and your application tier. There is a lot to talk about with this, but I like what I see, and so should the EF naysayers. I can’t do it justice here, but I do have a full post in the works about it. While you’re waiting, there’s a Hand’s On Lab for Ria. Azure There’s a lot to talk about with Azure from the announcement that SQL Data Services will support standard ADO.NET (and other TDS capable clients), to Windows Azure supporting PHP and Full-Trust code and beyond. I’ll save that info for my other blog. Blend 3 There is not enough I can say about Blend 3! The WPF team has always talked about the Designer-Developer Workflow. Blend 3 takes it to another level. The most compelling feature of Blend 3 is Sketchflow. The best description I can give of Sketchflow is a digital storyboard for mocking up an application that happens to produce a working application. Trust me you’ve got to see this! There are a metric ton of other new features in Blend (and that’s just what’s in the Preview), but Sketchflow is the most intriguing to me. So that’s what I’m excited about from Mix ‘09. What has you buzzing? February 28 Mozilla Lab Concept Series, Aurora, and FlowIn this post, I talk about the Mozilla Lab Concept Series, particularly Aurora, and how Flow fits into the picture. Read more here. February 24 Refactoring to Patterns: WPF Edition Part 1 The VisionI need to come up with a shorter title. I know there has been a lot of disdain lately for "”Big Process” or over documentation. But there are some documents that are worthwhile whatever methodology your subscribe to. One of those documents is the project vision and scope. Essentially, your project vision provides guidance for what the goals of the system are. As a rule of thumb, when considering a requirement ask “does this align with the project vision?” I don’t believe much in process for process’ sake. I think Jeff Atwood said it best (in a post that I read as a result of my experiment), there is no recipe for the perfect program. Patterns, practices, and principles are not prescriptive, blindly following them is akin to trusting Google maps to get you to a destination in a strange town during construction season. In many cases, you’ll be just fine, but there will be those times when you wish you were more familiar with That being said, I feel that creating a project vision is an essential first step in starting a software project. The process (like making a business plan) makes you think, “Why am I doing this?” In many cases, a well-written vision will help you sell a project to management. In other cases, the vision serves as little more than than a daily reminder of what you’re trying to do. From a project management perspective the scope portion of the vision helps the PM decide if a feature is in or out for a project. Of course it can be adapted to fit whatever process you’re using. So if you’re doing agile or iterative development, you’d have a broad project vision and scope as well as a more narrowly focused iteration scope that says what’s in for a given iteration. Up until now, my vision has been somewhat amorphous. The summary on the project page for “Flow” on codeplex is the closest I have to a project vision. Let’s rectify that situation. First Draft“Flow will be the most awesome software ever created. It will be able to read the user’s mind, anticipating what they want to do and respond accordingly. Flow will be so perfect that people will be willing to spend their life savings to acquire it.” Although it would be great for “Flow” to possess these qualities, this doesn’t work very well as a product vision. Before we dissect it, we need to know what qualities make a product vision good. Fortunately, there is a lot of material available for someone learning about project management. Of course, one of my favorite starting points over the past few years has been Wikipedia. After a few steps of searching (which would be shareable within a completed version of “Flow”), I found the SMART acronym. Basically the product vision should be:
I hope you can see why my original vision isn’t very SMART. Usually faulty goals within a vision aren’t that obvious. They’re more insidious like “…the best toaster on the market”. (Coincidentally, if you’re asked that question on an interview, they want you to question the definition of the best, not go about proving that it is.) Once More With FeelingAnyway, let’s try again to envision “Flow”.
There we are, I think our vision meets the SMART guidelines, with the exception of Timely. We haven’t placed a time frame on the release of Flow. It’s somewhat difficult for me to time this. I have a day job and family. (Including a new child on the way.) My heart wants to have the first version available by June. Reality says it will most likely be a Beta in September and V1 at year’s end. Of course all of that could change should more people volunteer to help (it is an open source project after all). Even then, there is a limit to how effectively the work can be distributed. We’ll see what happens though. February 23 Static Reflection: Say What?There’s a new oxymoron going around call Static Reflection. The basic gist is that by using expression trees you can do things that appear to be dynamic but in reality are checked at compile time. Like for instance, getting the name of a property for firing an INotifyPropertyChanged.PropertyChanged event. My colleague, Jon Fuller, showed me his code for Method Guards and my first comment was that this would be a great tool for implementing INotifyPropertyChanged. He informed me that he already went there and showed me that code as well. I wasn’t too happy with the idea of wasting your sole base class on NotifyPropertyChanged so I suggested that we use extension methods instead. After a bit of finagling with the framework (Events don’t like to be fired from outside their declaring class), here is the result: public static void SetProperty<T>(this INotifyPropertyChanged source,
Expression<Func<T>> propExpr,
Expression<Func<T>> fieldExpr,
T value)
{
source.SetProperty(propExpr, fieldExpr, value, () => { });
}
public static void SetProperty<T>(this INotifyPropertyChanged source,
Expression<Func<T>> propExpr,
Expression<Func<T>> fieldExpr,
T value,
Action doIfChanged)
{
var prop = (PropertyInfo)((MemberExpression)propExpr.Body).Member;
var field = (FieldInfo)((MemberExpression)fieldExpr.Body).Member;
var currVal = (T)prop.GetValue(source, null);
if (currVal==null && value==null)
return;
if (currVal==null || !currVal.Equals(value))
{
field.SetValue(source, value);
var eventDelegate =
(MulticastDelegate) source.GetType().GetField(
"PropertyChanged",
BindingFlags.Instance | BindingFlags.NonPublic).
GetValue(source);
Delegate[] delegates = eventDelegate.GetInvocationList();
var args = new PropertyChangedEventArgs(prop.Name);
foreach (Delegate dlg in delegates)
{
dlg.Method.Invoke(dlg.Target, new object[] { source, args });
}
doIfChanged();
}
}
Now you can use a strongly typed NotifyPropertyChanged declaration without using your base class public class PersonStaticReflection : INotifyPropertyChanged
{
private string _firstName;
private string _lastName;
public string FirstName
{
get { return _firstName; }
set { this.SetProperty(() => FirstName, () => _firstName, value); }
}
public string LastName
{
get { return _lastName; }
set
{
this.SetProperty(() => LastName,
() => _lastName,
value,
() =>
{
// do something useful here
});
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
For those concerned, you can statically cache the PropertyChanged field in a dictionary mapped to the object type so that you only have to reflect on it one time. February 18 Refactoring to Patterns: WPF Edition Part ZeroI guess I should give you some background before I go much further. The application we’re discussing here is called “Flow”. The name is metaphoric in several ways. The first metaphor is Flow as in a flow of thoughts or stream of consciousness. The second reference is to the work of Mihály Csíkszentmihályi, who has written a lot of books about the concept of “Flow” – a state of total immersion in one’s activities. Stream of ConsciousnessMy first impetus in designing “Flow” was dissatisfaction with my browsing experience. I wanted an application that would capture my stream of consciousness as I browsed the web – creating a mind map if you will. For an example of what I mean, read one of Jeff Atwood’s posts and open a new tab for every link in the post (to keep it fair only use the self-referencing links you can also skip any links that you know are dupes). Then do the same for each tab you’ve opened. Once you’ve done that you’ve got a pretty good approximation of how my browser looks at the end of a given day. Totally lost in my tabs is a good way to trace my path through coding horror. Imagine that my tabs represent a lengthy night of researching for a term paper, or digging into news on a company for deciding whether to invest my life savings in an IPO, or case research that could make sure that a defendant doesn’t get off on a technicality. This idea really hit home with me and I started typing about it. 4 hours and one thousand words later, I had a vision for what for lack of a better term I called a Streamcatcher. Shortly after doing this, I received a newsletter from Infoq.com pointing to an article about stream-oriented User Interfaces (was it really back in July when I first started doing this). My jaw dropped. It was as if someone had read my vision and written an article about it. Further research revealed that the idea of a Stream-oriented UI has been around for quite a while now. I started making a basic object model for an application that could visualize your browsing history as a graph of nodes and stumbled across a WPF panel for displaying a graph of objects. The next weekend I had a prototype browser that built the graph as you browsed. Anyway enough blabbing from me. Here is the original prototype I made so that you can get a picture of where we’re going. Ignore the ribbon. It doesn’t do anything. I was just experimenting with it and never bothered to take it out. Also the network graph component that I’m using will expire in 30 days after you first use the app, making the application useless. There is no way to save your graph. Right now it’s just a prototype. I’ll be uploading the code to the Codeplex project and starting the new codebase there as well.
To get started, place your mouse over the green dot and click on the button that appears. That will take you to google.com to start searching. An interesting search term is “flow psychology” (no quotes). I posted a video showing how flow works in an earlier post. Now if you’ll excuse me, I have 40 tabs of Coding Horror to read. February 17 Refactoring to Patterns: WPF EditionTo some it may appear that I have abandoned client side development for Azure. Nothing could be further from the truth. As I'll tell anyone who will listen, I'm just like a kid who's opened his presents on Christmas and found a new toy to play with. After playing with the new toy for a while, eventually I'll remember my old favorite and start playing with it again. (The real fun comes of course when I start playing with both together). It's not a Buzz Lightyear vs. Woody...it's more like Megatron vs. Galvatron. Anyway, I had to come back to Megatron at some point or another. And a recent thread within the WPF Disciples mailing list gave me that impetus. I've recently realized how effective refactoring can be for getting working code out rapidly while still addressing maintainability. My experiments with refactoring resulted in a technique I like to call "context sensitive architecture." A Practical ApplicationI'm not a huge fan of contrived applications, but sometimes we do what we must. This won't be one of those times. Let's say you have an application that could provide a rich view of your digital life and how that digital life is connected. Let's say for now the application could show contacts and bookmarks. Finally, lets say that the application wants to allow the user to add and edit contacts and bookmarks. How do you enable these scenarios? One way would be to create a CreateContactControl, an EditContactControl, a CreateBookmarkControl, and an EditBookmarkControl. I guess we want to allow the user to View their contacts and bookmarks. Now we have to add a ViewContactControl and a ViewBookmarkControl. What happens when we add RSS Feeds and Podcasts to the mix? Now we have to create six more controls and integrate them into the system. What's worse is that the main app has to know about each and every control in order to display them at the appropriate time. Of course we could use plug-in model to alleviate some of this pressure, but this could end up generalizing your application to the point where it is little more than a shell. There's nothing necessarily wrong with that, but I still think there's a compromise between the two extremes. Sometimes that compromise isn't very obvious. Hence, we use refactoring and iterative development to discover the compromise. The First IterationThe first iteration of a project should be used to implement what is called a "vertical slice" or two. This will allow us to realize the benefits of Agile development with the first delivery. Getting working software into the customer's hands quickly provides a compelling argument in favor of Agile development. I would actually recommend that you start with a minimal core team (2-3 members) for the first few iterations, this will enable you to minimize the overhead due to collaboration as the team takes its first steps into a new domain. It will also allow a few patterns to emerge before ramping up the velocity. Because you're targeting a smaller amount of functionality for the iteration, you might want to do a shorter iteration. I think two weeks should be adequate. Before we go any further, let's try to visualize this app with a pair of its scenarios: "Add a Contact" and "Add a Bookmark". The "Add a Contact" story is very simple: "As a user of the application, I want to be able to enter information about a contact for later retrieval and viewing: his or her first and last name, and email address." Likewise the "Add a Bookmark" story is equally simple: "As a user of the application, I want to be able to store information about a bookmark for later retrieval and viewing: the URL, and title of the bookmark." Based on these stories, we have identified two entities for our domain model: Bookmark and Contact. Here is the Bookmark: 1: using System; 2: 3: namespace Flow.Model 4: {5: public class Bookmark 6: {7: public Uri Address { get; set; } 8: public String Title { get; set; } 9: } 10: }The Bookmark is very simple, consisting of a Uri and a Title. We will probably identify more information that would be interesting to capture for a bookmark in a later iteration. For now, we want to get working code into the hands of our stakeholders as quickly as possible. Our second object of interest is the contact: 1: using System; 2: 3: namespace Flow.Model 4: {5: public class Contact 6: {7: public String FirstName { get; set; } 8: public String LastName { get; set; } 9: public String EmailAddress { get; set; } 10: } 11: }Let's make a pair of controls for creating new bookmarks and contacts. Following the WPF developer - designer workflow, I will make the first pass on the UI simplistic and straightforward (relying on my designer to beautify it later). After a few minutes in Blend, followed by some cleanup in Cider, I came up with a rather straightforward, minimalistic UI with the primary elements defined for optional elaboration by my designer:
Now that I have a way to create contacts and bookmarks. I should allow the user to view them. That’s easy enough. Let’s make a ListBox that shows the collection of contacts and another pair of controls that are read only. Rather than worrying about persistence at this point we’ll just store the information in memory. So What Next?We’ve delivered some basic functionality to our customers. More importantly, we have started the first path in our journey together. I will be placing the code on Codeplex. In addition I will be posting a screencast of me writing this code (once I figure how to get Camtasia to co-operate with me). This is something I’ve wanted to do for quite a while now. I just couldn’t find a project that I was compelling enough that would be able to grow from a very simple solution to a very interesting WPF application. I will reveal more about it over the upcoming weeks; in the process documenting the evolution what I feel is a very interesting application. Tune in for more info. February 06 Starting the New Year With a Bang!Yes I know it’s February already, but this should show even more how big the start of this year has been for me. First and foremost is the big announcement that the new year brought.
First and foremost, I’ve been named an MVP in Client App Development (for my community contributions with WPF). This is an incredible honor for me. In addition to the title, being an MVP provides me an opportunity to have better interaction and feedback with Microsoft especially with regards to my specialization. According to the program guidelines, the award is for my past activities and I am not required to do anything else. However, I want to leverage this opportunity to the fullest and will continue my community contributions going forward, both with regard to WPF and Silverlight as well as with Windows Azure.
Second, as an organizer for our local Alt.NET User Group, Indy Alt.NET, I’m excited about a few recent developments with the group. Chief among those being named an official INETA group – something that surprised me seeing that there was already an INETA group in the Indianapolis area. We are coming on our first anniversary and have seen our attendance stabilize at around 25 per meeting. With almost a year under our belt we have sat down and started a few initiatives. One major decision will be to incorporate as a non-profit organization (an idea we had thrown about for a while but were too busy with day to day operations to act upon). This action will allow us to apply for grants and begin some community outreach initiatives that we are all excited about. It will also make us more attractive to potential sponsors as certain donations to us will be tax deductible. Another initiative has been a marketing and sponsorship drive. We are trying to grow organically, but we have noticed that we have a chicken or egg scenario. Therefore, we are pushing our growth on multiple fronts. So far we are getting good feedback from our efforts. Our biggest initiative about which we are all very excited is planning for a local conference. More on that later ;) But wait there’s more! I just finished my first year with my current employer, Software Engineering Professionals. Management announced a number of initiatives here that are pretty exciting for me. I can’t necessarily talk about them right now, but it reaffirmed my decision to come here. I can honestly say that I have grown dramatically since I’ve been here. It is an amazing place to work, and I’m excited to see what the future has in store.
Finally, my family is counting the days until our latest addition is expected to arrive. Like I said, this year is starting off with a bang…and there’s more to come. I’ll keep you posted with new developments. November 03 As You’re Coding .NETI’ve put a summary of the buzz around Windows Azure on my blog. Will be creating more content soon. Working on an Azure Based twitter aggregator to feed the sections of AzureCoding.Net Maybe with some sync thrown in for good measure. I’ll be posting back here with the UI related stuff. For the most part, you might want to start looking there for my Cloud Topics and here for everything else. |
|
||||
|
|