Posts

Lessons from a 20 year-old web app

After I read " Why billing systems are a nightmare for engineers ", I thought it would be fun to write about my own experience. Specifically lessons I've learned from building and supporting a 20 year old (and counting) "ERP" web app. But first, let me explain a bit how this came to be. The web app is a general ledger, project management, inventory management, HR, and general " ERP " system (including billing, invoicing, foreign currency purchases, etc.) for 20-30 users at a small interior finishing supplies company which my grandfather founded. It has been used every day for at least 20 years. Building iteratively for years My Dad decided to give me a chance at building software for the family business before I was out of high school. I had shown an aptitude for programming and was making good money with friends building local websites. He built a COBOL system for the family business when he was my age, so the legacy was passed on to me (which I am ve...

Done button on iOS NumberPad with Xamarin

Image
There are a ton of potential solutions on the Internet for adding a Done button to a NumberPad-type of UITextField on iOS.  Unfortunately most of them are old, use custom images or even require iterating through sub views to find the target keyboard. Below is a solution -- using Xamarin -- to add a Done button without fear of index-out-of-bound exceptions or using out-dated custom images. The trick is using the WeakInputDelegate of the UITextField & adding a custom button to that. A full working project is available on github . public override void ViewDidLoad () { base.ViewDidLoad (); // Your stuff NSNotificationCenter.DefaultCenter.AddObserver ("UIKeyboardWillShowNotification", KeyboardWillShow); } public void KeyboardWillShow(NSNotification notification) { var doneButton = new UIButton (UIButtonType.Custom); doneButton.Frame = new RectangleF (0, 163, 106, 53); doneButton.SetTitle ("DONE", UIControlState.Normal); do...

Xamarin .xib Tree Hierarchy Cleanup

Image
Another annoyance with Xamarin Studio is when adding a new iPhone View Controller and the csproj's hierarchy is different than what you'd expect (or what is used in the mobile-samples ). So I whipped up another Python script to save me some time & appease my obsessiveness. Let's add a new iPhone View Controller simply called "MainMenu"... Notice how the tree hierarchy has the .designer.cs file nested underneath the controller .cs file -- and the .xib file is completely independent. Now let's run xamarin_tree_clean.py available at  https://gist.github.com/xeb/5907008 And when we head back over to Xamarin Studio, it will automatically reload the project file & our tree hierarchy will be clean again.

Switch Xamarin Studio to Xcode5 for iOS 7.0 Development (and back)

Image
I enjoy using Xamarin .  I also want to play with the Xcode5 Developer Preview . But sometimes I want to switch back & forth between Xcode5 and Xcode4.  Why?  Because of this: That's the message you'll get in Xamarin if you use Xcode5-DP.  So I hacked out a quick Python script to help me switch back & forth in my project. It's simple enough to just be worthy of a Gist.  See: xamarin_switch.py at https://gist.github.com/xeb/5890019 . Use it within the directory of the solution & csproj that you are working with.  Then just run the script & specify which verison of Xcode you want.  (Either a 4 or a 5 or "xcode4" or "xcode5"). Example: Again thats.... xamarin_switch.py xcode4 To go to Xcode4 + iOS 5.1/6.0/etc. and xamarin_switch.py xcode5 To go to Xcode5-DP + iOS 7.0 This did three things: Changed the SDK Location of Xamarin Studio Changed the first CSPROJ file to the correct iOS Build version Launched Xam...

Unconventional Technical Leadership

I just finished reading David Byttow's Effective Technical Leadership post.  There are some unsaid ideas that he did not present that I wanted to share.  But first... Why listen to me?  I'm a Lead Software Engineer at a large video game developer ( google me ).  I've stopped posting to this blog since joining the company as a Software Engineer in 2010.  But in 2 years, I've been promoted 3 times and now lead a team that develops a massive amount of live operation.  I will get called at 3am if something breaks.  Or is too slow.  There is no one above me that has more technical knowledge of the systems I work on.  Once its escalated to me -- I have to fix it.  If something happens 1-in-a-million times in our codebase, it may happen 100 times a day. It is not easy  keeping people productive, effective & reliable in a medium sized team.  Below are some random bits of advice I can offer after spending a decade creating la...

Applying WebInvoke without an Attribute

Haven't posted in a long time but thought I'd post this bit of WCF extensibility I was working on at home. There is nothing on the Internet about how to do this & I felt I should figure something out. Scenario: You have legacy WCF services that you want to switch to a WebHttpBinding w/ JSON but don't want to update 1,337 service contracts to include a WebInvoke attribute, UriTemplates and Request/Response Body Types In this scenario I'll be assuming use of IIS and Windows Process Activation Services to host your service. The WebInvokeAttribute implements IOperationBehavior. So what we need to do is somewhere in the WCF stack apply this operation behavior programmatically to our Endpoint's Contract.Operations. Let's start from the bottom up & take a look at an extension method that does this. /// <summary> /// Automatically applies the Web Invoke behavior to all operations in the collection /// </summary> /// <param name="operatio...

MapReduce in C# using Task Parallel Library

Back in August I starting playing with a C# implementation of Google's MapReduce algorithm. The implementation was based on something Stephan Brenner did, although I completely refactored it. Today I added a little bit of logic to split up the actual execution of Map & Reduce in this implementation using the Task Parallel Library in .NET 4.0. Check out the source code for MapReduce in C# on GitHub. Below is an excerpt from the Tests on how to implement the library. Counting Words in Files public static List<KeyValuePair<string, int>> Map(FileInfo document, string text) { var items = text.Split('\n', ' ', '.', ',','\r'); return items.Select(item => new KeyValuePair<string, int>(item, 1)).ToList(); } public static List<int> Reduce(string word, List<int> wordCounts) { if (wordCounts == null) return null; var result = new List<int> { 0 }; foreach (var value in wordC...

Require comment / message on all SVN commits for Visual SVN Server

(I've been posting a lot the last few days!) Something that drives me nuts is not having a comment or message when looking at SVN history. It's impossible to know what went on. Even a bad comment is better than no comment. SVN hooks are a great way to solve this. If we make a pre-commit.bat file that checks the commit data for a comment, returns an error code of 1 if it wasn't found (with some text) or returns 0 if the comment is there. Check out the pre-commit hook that I found online (thanks, Anuj Gakhar!) or check out the hook below. @echo off setlocal rem Subversion sends through the path to the repository and transaction id set REPOS=%1 set TXN=%2 rem check for an empty log message svnlook log %REPOS% -t %TXN% | findstr . > nul if %errorlevel% gtr 0 (goto err) else exit 0 :err echo. 1>&2 echo A log message or comment is required to commit 1>&2 exit 1 This works perfectly except for 1 downfall -- you have to distribute it in every freaking reposito...

Using ref Keyword with Reference Types in C#

One of our developers was using the ref keyword in a method that needed to replace the value of a property of the method's parameter. In other words... public class Person { public int ID { get; set; } public string Name { get; set; } public string Email { get; set; } } public static class ReferenceExample { public static void Main() { var person = new Person { Name = "Mark", Email = "none@none.com", }; Save(ref person); Console.WriteLine(person.ID); Console.ReadLine(); } public static void Save(ref Person person) { person.ID = 1; // Pretend this saves to a database or something } } The thinking is correct. Person needs to be passed by reference. So why not use the ref keyword, right? Well...Person is already a reference type . So if we are just replacing properties, we don't need the ref keyword. Removing it changes nothing with our code. T...

Get the name of a property as a string in C#

Another developer showed me something very useful with Expression Trees in C# (thanks, Pierre! Full credit goes to you). To show you the awesomeness of it all, let's start with a class called Person . public class Person { public string Name { get; set; } public string Email { get; set; } } Now let's say I have an instance of Person var person = new Person { Name = "mark kockerbeck", Email = "noneofyourbusiness@face.com", }; Imagine creating a Dictionary<string,string> of this particular Person's properties (e.g. "Name" and "Email") and the corresponding property values. We could easily do something like the following: var dictionary = new Dictionary<string, string> { { "Name", person.Name }, { "Email", person.Email }, }; But there is unnecessary redundancy and repetition in this. We have to say the property twice (and as a messy string no less!). Well, we could use reflection... var di...

Service Cloud - dynamic calls to a cloud of WCF services

Image
For awhile, myself and another developer have been trying to build a working prototype of an idea he proposed for a Service Cloud. Essentially the Service Cloud is a collection of WCF services hosted on a number of servers and environments that can all communicate with one another via a common interface. An "application" would then be built by orchestrating these services together. Instead of the application adding service references for each of the services it needs -- it would simply send a request to the "Gateway" service and it would figure out the rest. It would call the other services. Finally, when the execution is complete and your request has bounced all over the cloud, you get a response that many services have built together. I finally was able to create a working prototype (albeit completely contrived). The Service Cloud prototype is available on GitHub, see: http://github.com/xeb/ServiceCloud . Client The client is simple. The client adds a WCF Se...

New & Fun vs. Tried & True

I love new technology -- .NET 4.0 and the DLR are a dream come true. I cannot wait to convince other developers of the awesomeness of having IronPython for middleware supported by compiled C# on the backend. But before I go upgrading existing client sites to 4.0, I need to be sure it will work. I just want to see it be successful from start to finish. I am skeptical by nature and want results before jumping in bed with any new tech. Not that I don't think Microsoft did an amazing job with the latest framework -- its just that I'm not as familiar with the "workarounds" that I need to learn for things. And yes, there will be workarounds -- I have yet to see perfection in software ( only a few things come close). From my experience it seems that developers fall into two general categories when faced with new technology decisions. Hopefully they change from one category to another. If you're like me, you change on a project by project basis. New & Fu...

TwoRingBinder - a Custom ASP.NET MVC Model Binder

I haven't posted in a few months. Been busy at work and starting playing WoW (I know -- its awful but its fun). But a few weeks ago I made a Custom ModelBinder -- called TwoRingBinder -- for ASP.NET MVC. Ok, it's not an implementation but rather a class inheriting from DataAnnotationsModelBinder that allows for easier custom Binding methods. I put it on github but will explain how to use it below. Download or check out the meat of the code. Essentially, TwoRingBinder allows you to write Binding Extensions instead of writing your own Custom Model Binder every time you want to do something tricky or different with Model Binding. Example: We have a model called SignUp . SignUp has FirstName, LastName, Origin, IsFemale and FromRoot properties. Only the FirstName and LastName properties will be bound from a form via a ValueProvider; however, we need IsFemale to have a value (assume for a service of some type). Now, we don't want a checkbox on the site for people to se...

ASP.NET MVC and MSBuild via Command-Line

I struggled with this one for a couple hours & wanted to post some help. I'm trying to move towards better deployment processes. I'd like to use TeamCity but until then, command-line will do. It's how I roll anyways. When I first ran MSBuild on my ASP.NET MVC CSPROJ file I got the following error: C:\Projects\MvcApplication.WebUI>msbuild /p:Configuration=Debug MvcApplication.csproj Microsoft (R) Build Engine Version 2.0.50727.3053 [Microsoft .NET Framework, Version 2.0.50727.3603] Copyright (C) Microsoft Corporation 2005. All rights reserved. Build started 5/18/2010 9:27:29 PM. __________________________________________________ Project "C:\Projects\MvcApplication.WebUI\MvcApplication.csproj" (default targets): Target ResolveProjectReferences: C:\Projects\Assembly.csproj(200,11): error MSB4019: The imported project "C:\Microsoft .CSharp.targets" was not found. Confirm that the path in the declaration is correct, and that the file exists on...

Why TradingBlox is so Awesome

TradingBlox is a relatively expensive piece of software that you've (probably) never heard of. You may never use it. But I still think you should know about it. I've been passionate about the financial markets for years. Later I'll explain this month why you should at least know something about them. I had the pleasure of working at Carmichael and Company LLC and learned a great deal about trading from Ralph Carmichael. It excited a passion in me. This passion was fueled by books like: Market Wizards, Reminisces of a Stock Operator and The Way of the Turtle. Also this little PDF about the original Turtle trading rules really helped. After trying to program my own recreation of the Turtle rules, I stumbled upon TradingBox. It did everything I wanted and more. It has an amazing community. It supports trading & optimizing multiple markets with the same system (which was a pain -- if not impossible -- using TradeStation). TradingBlox lets you program trading r...

Spark - Optional Parameters in Partials

While on the topic of the Spark View Engine , there is an easy way to make a parameter of a partial optional so you don't always need to pass a value when calling the partial. Simply define the variable as part of the viewdata property. <!-- samplePartial.spark --> <viewdata optionalParameter="string" /> <a class="active?{optionalParameter == "home"}">Home</a> That's it. Now you can call the partial by itself... <samplePartial /> ... or with the optionalParameter ... <samplePartial optionalParameter="home" /> A helpful trick that I couldn't find a lot about online.

Spark - Recursive rendering of partial files not possible (but it is!)

We've been using the Spark View Engine a lot at work. I absolutely love it. Our front end developers love it (they don't need to re-learn something like we had to for NHaml ) and if they don't want to use Spark's features, standard HTML works without problems. During one project, I was making some contextual menus. I wanted to call a Spark partial recursively in order to not repeat myself & keep things flexible for the future. Unfortunately Spark specifically disallows this. If you try it, you will get an Exception that states "Recursive rendering of partial files not possible" . Well that just sucks. I understand the limitation in the View Engine itself but there is a way around it. Not super elegant but definitely functional without sacrificing anything other than style . I posted the following example in the Spark project itself. The trick is using the HtmlHelper 's RenderPartial method. Let's say we have a partial called: navigation...

How to Troubleshoot a Problem

Building computers early on in life was an invaluable experience. Fighting with mobos & hunting for drivers taught me more about software development (& customer support) than hardware. I've been trying to summarize those lessons into an easy framework for debugging, troubleshooting and fighting most problems. Below is just what I have so far. Hopefully it's useful in some way. 1) Don't Panic - if this sounds familiar, congrats, you're a geek. You have to be calm & stop freaking out to be of any use. Someone going ape shit in your face is the fastest way to stop your brain from working. So take a moment, read Zen Habits and just chill for a second. 2) Identify the Problem - before doing anything, ANYTHING, you must figure out what's going wrong. Is the page not displaying? Is an error appearing? What's in the stack trace? What is happening that shouldn't be? 3/10 times you will stop here because nothing is wrong at all. Someone wa...

TrustButVerify - simple jQuery validation powered by LiveValidation

I really like the way LiveValidation runs; however, I REALLY LOVE jQuery selectors & chaining. Unfortunately the LiveValidation approach to validation doesn't feel right when looking at a lot of field-specific validators surrounded by super terse jQuery syntax. So I decided to make a small 79-line wrapper-type of plugin that is powered by LiveValidation but comes with all the power of jQuery's selectors, chaining and... well, jQuery. I called the plugin, TrustButVerify . Check it out & let me know your thoughts or if there is room for improvement (which there definitely is). I have NOT exposed all of the LiveValidation methods; just the ones I found useful & necessary :-p Here's a sample of some validation: $(document).ready(function(){ $('#form .required').required(); $('#email').validEmail(); $('#zip').matches(/^\d{5}$/); $('input.address').required().validate(someCustomFunction, 'your address is out of our area ...

Convert SQL types in destination to SQL type in source

Another little script I needed for today. Feel free to expand on the CASE statement for your own types (which I will do should I need to run this again). /* Will transform destination table's column types to match the source database's (when column names match) codesnippet:83d07e82-3866-4877-849f-0ae06322b9fb */ declare @destination varchar(50) declare @source varchar(50) ---- Configuration ----- set @destination = 'PlanImport' set @source = 'Plan' ------------------------ declare @i int declare @count int declare @sql varchar(8000) declare @columnName varchar(8000) declare @columnType varchar(8000) declare @columns table (id int identity(1,1), columnName varchar(50), columnType varchar(50) ) -- insert source columns that are in destination insert into @columns select source.[Name], (CASE source_types.[Name] WHEN 'decimal' THEN source_types.[Name] + '(' + cast(source.[precision] as varchar(50)) + ',' + cast(source.[scale] as varc...