I just finished forming a new company called Crafting Bytes with Brad Cunningham and Ike Ellis. We wanted to start taking on bigger projects using the techniques that have made us so successful as consultants. Over time we have noticed that we do much better with the projects when we take control of the project management as well as the development rather than simply augmenting the development staff. What is different about our project management style than the project management style of other companies that we work with?

One major difference is that we don’t use scrum. In a sprint developers spend a lot of time estimating the work. Estimating can be important when the estimate is used to determine whether or not the work should take place at all. However, in most cases companies were using the estimate to inform management when the product was supposed to ship, so that they could relay that information to the customer. It would be a better idea to relay the information to the customer *after* the work has been completed. It is much more accurate that way. The other reason managers were requiring estimates was to figure out how much work should be completed this sprint. So in other words managers were requiring estimates for the sole purpose of the project management methodology they were using.

The thing is estimates take a lot of time, and they are rarely accurate. Our thought was let’s forget scrum and just go with a simple Kanban board (from the Lean school of thinking). By doing this we can save ourselves countless hours of trying to figure out how much time things are going to take, and spend more time simply doing them.

OK, so that saves a couple days every sprint, but then what is the purpose of having a project manager at all? I admit that the project managers of many companies are totally unnecessary. You know the type, they spend most of their time polling individual people “are you done yet”. They could easily be replaced by voice recognition software that recognizes the word “yes”. This isn’t really project management, it is instead project reaction. Project *management* would be managing the work of the project, prior to it starting. In short a project managers job is to figure out which work is the most important and which work is so unimportant it doesn’t need to be done at all. Great project managers remove all unnecessary tasks, that is all tasks that don’t lead to working software, and prioritize which features are the most important for the business and the user. In short they control the prioritized list.

Thinking of project management as simply controlling the list of things that need to get done and prioritizing the most important simplifies the job of the project manager and helps the team achieve minimum “time to value” – a vastly underrated metric.

This blog was cross posted on the Crafting Bytes blog at Project Management As A Prioritized List

I think this is my 6th year speaking and 7th year attending at SoCalCodeCamp (San Diego edition).  For the past several years I have tried to give an advanced talk and an intro talk.  For the advanced talk I decided to give OData again for several reasons.

  1. Nobody else was speaking on it
  2. I has already signed up to give a webinar on it
  3. I still think it is relevant
  4. It is so flipping cool

The slides and demos for that are in the previous blog post.

When it came time to pick an intro talk I combed the SoCal Code Camp web site looking for gaps.  The gap I found was not what I am used to speaking about.  I was going to have to give a talk about . . . the front end.  (NOOOOO!!! Wait, I mean Sooooo what? What’s the big deal about the front-end?)  Specifically, I wanted to give a talk about using an off-the-shelf CSS framework called Twitter Bootstrap.  I had used it in my job, and in my side project, so I figured that should qualify me :) .  I put in the abstract and then forgot about it.

Months go by, and here it is the week before the talk.  I check back and realize a couple of things

  1. I had not used Twitter Bootstrap since I wrote the abstract
  2. There are over 80 people interested in the talk
  3. My daughter Julia has a soccer tournament on the same weekend

Long story short I wasn’t quite as prepared as I should have been.

The first day was pretty hectic.  First I saw Robin Shahan give a talk on Windows Azure in Real Life.  She good-naturedly accused me of heckling, but I think I was just encouraging audience participation :) .  The second talk I saw was Search engine building with Lucene and Solr, but I left as the speaker transitioned into Solr.  I ran home to help Julia get ready, and then back to Code camp to see Windows Azure Mobile Services by Bret Stateham.  Great talk as always, but I had to leave early to see the soccer game, which they lost 2-3.  I hustled back for NancyFX, which was probably my most influential talk of the weekend, then left again to see the final minutes of a 3-2 victory. Woohoo!!!

That night at the Geek dinner we found out that Woody was passing the baton after 8 years of running the SoCal code camps to Hattan. I also found out that night that my daughters team was playing the Surf at 10:00 (the same time as my OData talk) which sucked.

The second day I suffered through Data Flow Architectures, before giving my OData talk.  While speaking I learned that my daughter’s team lost the 2-2 game in penalty kicks.  The bright side to that was I didn’t need to worry about a conflict that afternoon.  I then went on to see Timothy Strimple on Git and GitHub.  I stayed in the room for Llewellyn and Chris Lucian talking about Agile Metrics, which helped me see some problems with the project that I was on.

The Twitter Bootstrap talk was the final talk of the day.  It was in the TV building, and the room could probably only support 30-40 people, but it was packed.  People were standing along the outside.  Also mildly surprising there were children in the class!  And they asked questions!?!?  And the questions were good!!!

I had no idea how the timing of the talk was going to go, and in fact it ran over, but it was very well received.  I was applauded (some even gave standing ovations – see previous paragraph) and several people stayed behind to congratulate me on a talk that I felt could have definitely gone smoother. I am glad everyone enjoyed it.

Thanks everyone for attending.  Here are the demos and slides. Slides are also on slideshare.

Thanks to everyone that attended the WCF Data Services (OData) webinar.  Here are the WcfDataServicesIntro slides.

I promised I would report on the issue we ran into during one of the demos.  The first issue was Resource not found for the segment ‘Titles’.The reason that I wasn’t hitting it when I tested was because I was querying for a book already in the system.  However, The fix was very simple (after a Google search).  I needed to add:

context.IgnoreResourceNotFoundException = true;

There was one additional error that I encountered, which I did know about but I didn’t hit it until after I fixed the other error.  The enum property that I added was unable to be serialized back across the wire.  The simple fix was just to make those properties internal.  WCF Data Services only cares about public ones.  With that everything ran.

Here are the BooksDataService demos.

I have received some flack for my lack of blog posting. To defend myself let me state that for the past year I have been busy. Really busy. There were many days where I didn’t have time to eat or sleep, much less blog.

After April 12th all that changed. I took a vacation and recharged my batteries a little. Now that I am “not so busy” I have decided to start blogging again. Looking back it wasn’t that I didn’t have interesting things to share, it is just that I didn’t have time to write them up properly. In Word Press and OneNote combined I have over 70 drafts of blog entries. So I am making a public commitment – 10 blog entries a month for the next 3 months to try and catch up.

I have decided to back date any blogs which were started so that they make sense chronologically to me. For example my first entry is going to be about updating the blog to use HTML5 and CSS3. I performed a demo of doing that for the spring quarter UCSD Extension ASP.NET MVC class. So I am going to file it as if I was able to write it up at that time, because that is where I did the research. However some of the entries are really just titles and a couple of bullet points, so those will get new dates.

Here I go…

[Update: Adding Converting Blog to CSS3 on May 3rd]

When I started doing more complicated things with ASP.NET MVC it was using Razor. In some ways that was unfortunate because some of these things were actually a little easier in prior versions. It starts to get complicated when you start composing partial views and multiple javascript files. First some Javascript files depend on other javascript files. And secondly partial views need certain scripts to be included that the main page doesn’t necessarily know about. The problem is that Razor doesn’t really deal with these things very well.

For this blog entry I am going to focus on getting JavaScript files included from partial views. This question has been asked numerous times on Stack Overflow

  • http://stackoverflow.com/questions/863436/is-it-bad-practice-to-return-partial-views-that-contain-javascript
  • http://stackoverflow.com/questions/912755/include-javascript-file-in-partial-views
  • http://stackoverflow.com/questions/4707982/how-to-include-javasscript-from-a-partial-view-in-asp-net-mvc3
  • http://stackoverflow.com/questions/5376102/mvc-partial-views-and-unobtrusive-jquery-javascript
  • http://stackoverflow.com/questions/7556400/injecting-content-into-specific-sections-from-a-partial-view-asp-net-mvc-3-with
  • http://stackoverflow.com/questions/11098198/is-it-ok-to-put-javascript-in-partial-views

In fact, I bet if you put all of the questions in 1 it would have quite a point total. But it is spread into so many slightly different questions that it is tough to quantify.

So first to define the problem. The ideal place for scripts is right before the close of the body tag. The default template’s master/layout view contains a scripts section for this purpose. Unfortunately sections can only be defined, not added to. So that means that the main view is the only one that can place script files in that section. It can get very awkward if there are script files that are very specific to the partial view, especially if the main view includes a number of partials. Basically the master view has to maintain the list of scripts needed by the entire tree of partial views.

Let’s make the problem more concrete. Let’s say I have three main view that include a partial view. That partial view uses another partial view. I change the leaf partial view so that I need some JavaScript. I have to find out where all of the views are that include me (but of course no view includes me directly), and add the script to those views. In short – YUCK.

While researching a solution to the problem, I came across a couple of promising solutions, namely:

http://stackoverflow.com/questions/5433531/using-sections-in-editor-display-templates/

And

http://forloop.co.uk/blog/managing-scripts-for-razor-partial-views-and-templates-in-asp.net-mvc

The first didn’t take into account paths, and the second was way too complicated in terms of how to use them, so I came up with this nice simple hybrid of the two solutions.

Here is an example of its use
Either at the top of the file or the web config, need to use the namespace

@using PartialsWithScripts.Helpers

To include a script in a partial view simple add it like so:

@{ Html.MyAddScriptFile("~/Scripts/App/contact.js"); }

Here is the code

public static class ScriptHelpers
{
    const string ScriptContextKey = "ScriptContext";

    public static void AddScript(this HtmlHelper htmlHelper, string path)
    {
        var scriptContext = GetScriptContext(htmlHelper);
        scriptContext.Add(path);
    }

    public static IHtmlString RenderScripts(this HtmlHelper htmlHelper)
    {
        var httpContext = htmlHelper.ViewContext.HttpContext;
        var scriptContext = httpContext.Items[ScriptContextKey] as HashSet<string>;
        if (scriptContext != null)
        {
            var builder = new StringBuilder();
            var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext,
                                htmlHelper.RouteCollection);
            foreach (var scriptFile in scriptContext)
            {
                builder.AppendLine("<script type='text/javascript' src='" 
                    + urlHelper.Content(scriptFile) + "'></script>");
            }
            return new MvcHtmlString(builder.ToString());
        }
        return MvcHtmlString.Empty;
    }

    private static HashSet<string> GetScriptContext(HtmlHelper htmlHelper)
    {
        var httpContext = htmlHelper.ViewContext.HttpContext;
        var scriptContext = httpContext.Items[ScriptContextKey] as HashSet<string>;
        if (scriptContext == null)
        {
            scriptContext = new HashSet<string>();
            htmlHelper.ViewContext.HttpContext.Items[ScriptContextKey] = scriptContext;
        }
        return scriptContext;
    }
}

…for Data based services

There are two basic problems with using WCF to expose data services and both boil down to producing too many methods
1) You have to create a minimum of 5 methods per type that you want to expose (CRrUD)
This is basically – “I have too many types of things to expose”
2) You have to create a new method every time a client comes up with a different way to query the data
a. Get Orders by Product
b. Get Orders by Customer
c. Get Order By OrderId
d. Get Orders by Category
e. Etc
This is basically “There are too many ways to query my data”

There is one other reason that is sometimes overlooked, which is you have to modify all those methods when you want to do something across the board, like service side paging or filtering out rows based on the current customer. These use cases are difficult to apply in an aspect oriented fashion and often require the modification of many different pieces of code.

While teaching my fall MVC class, I was under a space constraint on both my e-mail and my hard drive. (Since then both have been cleaned out and upgraded). Anyway I was receiving these huge files containing a whole bunch of packages that I already have on my machine, and could easily download again. So I decided to make a video to demonstrate how to use NuGet to fix the problem.

You can watch the video on my YouTube channel

I use WordPress for my blog. I wanted to update the bog to use HTML5 and CSS3. It wasn’t like I was using tables for layout or anything but there were three things that I didn’t really like the look of.

The first thing I wanted to fix was the Web font. I was using JavaScript to produce the font, and it was not giving good results in all browsers. I searched for and found the Whiteboard regular font I was using. Unfortunately not all font files are supported in all of the browsers. To support all browsers you need at least 2 files. I downloaded and copied all of the necessary files (ttf, eot, woff, and svg). Then I edited my main stylesheet and added this to the top

/* @font-face kit by Fonts2u (http://www.fonts2u.com) */ 
@font-face
{
	font-family:"Whiteboard";
	src: url("House_Whiteboard_font_by_callsignKateJones.eot");
	src: url("House_Whiteboard_font_by_callsignKateJones.eot?#iefix") format("embedded-opentype"),
	url("House_Whiteboard_font_by_callsignKateJones.woff") format("woff"),
	url("House_Whiteboard_font_by_callsignKateJones.ttf") format("truetype"),
	url("House_Whiteboard_font_by_callsignKateJones.svg#Whiteboard") format("svg");
	font-weight:normal;font-style:normal;
}

I removed the typeface.js scripts and the extraneous styles, and voila, I now had working fonts in all browsers.

The next thing I wanted to focus on was the text on the sticky note. I wanted it to look written on. For this I needed the new CSS3 rotate transform

.sticky
{
	-webkit-transform:rotate(-9deg);
	-moz-transform:rotate(-9deg);
	-o-transform:rotate(-9deg);
	/* filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=-0.1); */
	-ms-transform:rotate(-9deg);
}

The last thing I didn’t like was the whiteboard boarder. It looked alright in Chrome (which was my default browser, but not so good in IE. I tried a couple of things including border gradients and background gradients, but I couldn’t get it to look right. Finally I had to resort to JavaScript which sucks.

I missed the first session because of lack of sleep and the fact that I hadn’t finished my slides for the day’s second talk. I came in at the end of Bret Stateham’s talk on Getting Started on Azure. I didn’t expect anyone to show up for my talk on Azure Tricks and Tips because of the advanced nature of the talk and that not many people are doing Azure yet. I was pleasantly surprised to find 10-15 people there, which was a great number for that kind of talk. The talk was well received and there were lots of good questions. I have uploaded the slides for the talk.

Afterwards I went to lunch with the DM gang. After I came back I was going to check out David Pallmann’s talk but I was about five minutes late, and it was in the same room as mine, so it was hot stuffy and crowded. Instead I ventured over to John Bowen’s talk on the Future of XAML for XAML Developers, which was in a much nicer room. I wanted to be in the same room for the talk after the next one, and Llewellyn assured me that it was going to be crowded, so instead of heading over to several other talks I just hung out in the same room and suffered through Fundamentals of Metro Style Applications. Then it was time for my favorite talk of the day – Michael Palermo’s HTML5 for the Real World. The crazy thing was that it was my favorite talk despite knowing all the material! His dynamic and engaging style was simply fun to listen to. After that was over I headed over to a fairly good talk by Paul Mendoza on Writing Maintainable JavaScript.

The Geek dinner was great – Lllewellyn was congratulated on the schedule, and I met a few people and had some interesting conversations on the CAP theorem and light particles as well as digitizing old film.

I was undecided as to which topic to attend first the next morning. On a whim I decided to attend the Hacking Your Memory session. Much to my surprise that became my favorite session of the entire camp – It Was Awesome! The speaker (Gary Hoffman) did a great job, the slides were well prepared, the topic was interesting and the audience was really engaged. Check out the site if you are interested.

Next I was trying to decide between WordPress Ninja!, and .NET TDD Kickstart. by Barry Stahl whom I had met two nights previously. I made the wrong choice and attended the WordPress Ninja! talk, which should have been renamed WordPress Beginnner!. During lunch Llewellyn talked me into doing the afternoon sessions that was supposed to be with Woody Zuill, but due to family emergencies Woody had to cancel. I begged out of the first one to attend a Node.js talk. I then trekked back over and helped give the talk on Testing EF, ASP.NET and ASP.NET MVC. I stayed in the room to attend the final talk User Driven Development which had some interesting discussion.

Great conference as always. Kudos to Woody Pewitt, Bret Stateham, Llewellyn Falco, and the rest of the volunteers for their efforts.

I am by no means an expert on Workflow. But after e-mailing back and forth with Jim Bears and Dave McCarter about a possible talk for the July meeting of the San Diego Developers Group, we concluded that not many people understand, use, or appreciate workflow. This could be due to bad experiences they have had in prior versions. Since the 4.0 version has addressed a lot of those shortcomings, we decided that it would be a great topic for discussion at a user group.

As per usual, I was too busy to prepare for the talk more than a day in advance. But I put together some slides, and formed a pretty good idea of the demo I wanted to do before I went in.

The first hour of the talk went pretty well. It was when I got into the unrehearsed part of the demo that things started to go awry. I had packaged up the first demo into a custom activity, and was trying to reuse that in a flowchart activity. Also I was switching from a WorkflowInvoker to running the workflow from a WorkflowApplication. At the same time I was adding persistence. I noted that I was still passing in the custom activity and not the workflow that contained the Flowchart, but I knew that something else was going on. I eventually found it (I was forgetting to call Run on the WorkflowApplication). Once I fixed that however, I forgot to go back and switch to the outer activity. That’s was the reason that nothing else was working.

This morning before I went to work, I fixed that problem, and corrected a couple of typos in the slides. Now that I am back home, I am going to finish the rest of the demo. That was always my plan, because I didn’t think that I would have time to do everything live.

I had already created one event – the completed event. But now that I allow the workflow to persist I want to capture another event – the PeristableIdle event

Here is an example of hooking that up:

app.PersistableIdle = e =>
{
	Console.WriteLine("Persisting...");
	_persistingEvent.Set();
	return PersistableIdleAction.Persist;
};

then I want to change my main from this:

WorkflowApplication app = CreateNewWorkflow();
app.Run();
_completedEvent.WaitOne();

to this:

WorkflowApplication app = CreateNewWorkflow();
app.Run();
_persistingEvent.WaitOne();
app.ResumeBookmark("readPrizeCode", Console.ReadLine());
_completedEvent.WaitOne();

Run it again, and everything works, but now what happens if I close the console application after receiving the prize code?
I need someway of loading the existing workflow, but I don’t have anything that I can load it by. As I mentioned last night there are a couple of ways to do this:
1) by using Promotable properties so that some of your properties are persisted along with the workflow.
2) Just tracking the mapping between your custom property and the instance ID from another table

I chose the second option, and added in the DataAccessLayer to do this already, but to take advantage of this feature I need to add the mapping record when it goes idle and take out the mapping when it completes. The final result looks something like this:

static readonly ManualResetEvent _completedEvent = new ManualResetEvent(false);
static readonly ManualResetEvent _persistingEvent = new ManualResetEvent(false);
static readonly ManualResetEvent _unloadedEvent = new ManualResetEvent(false);

static void Main(string[] args)
{
	string email = null;
	while (string.IsNullOrWhiteSpace(email))
	{
		Console.WriteLine("Enter your e-mail address:");
		email = Console.ReadLine();
	}

	bool done = false;
	while (!done)
	{
		WorkflowApplication app = CreateNewWorkflow(email);

		Guid instanceId;
		using (var session = new EfSession())
		{
			instanceId = session.Workflows.GetWorkflowInstance(email);
		}
		if (instanceId != Guid.Empty)
		{
			app.Load(instanceId);

			string prizeCode = null;
			while (string.IsNullOrWhiteSpace(prizeCode))
			{
				Console.WriteLine("Enter your prize code:");
				prizeCode = Console.ReadLine();
			}

			app.ResumeBookmark("readPrizeCode", prizeCode);
			_completedEvent.WaitOne();
			done = true;
		}
		else
		{
			app.Run();
			_unloadedEvent.WaitOne();
		}
	}
}

public static WorkflowApplication CreateNewWorkflow(string email)
{
	IDictionary<string, object> outputs = null;
	var app = new WorkflowApplication(
		new QuestionForPrize());
	app.Completed += e =>
	{
		outputs = e.Outputs;
		Console.WriteLine("Removing instance {0}...", app.Id);
		using (var session = new EfSession())
		{
			var instances =
				from wi in session.Workflows.All
				where wi.EmailAddress == email && wi.WorkflowInstanceId == app.Id
				select wi;
			var instance = instances.SingleOrDefault();
			if (instance != null)
			{
				session.Workflows.Delete(instance);
				session.Save();
			}
		}
		_completedEvent.Set();
	};
	app.PersistableIdle = e =>
	{
		Console.WriteLine("Persisting instance {0}...", app.Id);
		var wi = new WorkflowInstance
		{
			EmailAddress = email,
			WorkflowInstanceId = app.Id,
		};
		using (var session = new EfSession())
		{
			session.Workflows.Add(wi);
			session.Save();
		}
		_persistingEvent.Set();
		return PersistableIdleAction.Unload;
	};

	app.Unloaded = e =>
	{
		Console.WriteLine("Instance {0} has been unloaded", app.Id);
		_unloadedEvent.Set();
	};

	app.InstanceStore = GetInstanceStore();
	return app;
}

private static InstanceStore GetInstanceStore()
{
	var instanceStore = new SqlWorkflowInstanceStore(
		ConfigurationManager.ConnectionStrings["Workflow"].ConnectionString)
	{
		HostLockRenewalPeriod = TimeSpan.FromSeconds(1)
	};

	InstanceHandle handle = instanceStore.CreateInstanceHandle();
	InstanceView view = instanceStore.Execute(
		handle, new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30));
	handle.Free();
	instanceStore.DefaultInstanceOwner = view.InstanceOwner;
	return instanceStore;
}

Here are the slides and demos for the talk. Thanks everyone for coming!