Contents tagged with .NET

  • Live Kitten Juggling with ASP.NET MVC

    Are you as excited as I am about ASP.NET MVC but want to know more. Or have you been struggling all your life in Web Forms Hell and want to make the leap to MVC and don’t know where to start or who to turn to?

    kitties_small

    Jon Galloway and Christopher Harrison are presenting a fast-paced live virtual session (no travel required, except to get from the couch to the computer which I know is a task but we can do it) that walks you through getting introduced to MVC, Visual Studio, Bootstrap, Controllers, Views, and bears oh my!

    It’s a free-as-in-beer all-day session. If you know some C#, a little HTML, and some JavaScript and want to amp up your game then I encourage you to drop by. The free Microsoft Virtual Academy event runs from 9:00am – 5:00pm PDT on June 23, 2014. Check out this page for more details where you can also register for the event.

    See you there!

  • Code to Interfaces. Right. What’s an Interface?

    The premise of coding to interfaces has been around for awhile now. The concept is simple. Given a definition of something you create things based on that definition. That might be a horrible description of an interface but I didn’t want to go all Computer Science on you.

    Interface? What’s an Interface?

    Here’s a simple interface:

       1: interface ICustomerService
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     IEnumerable&lt;Customer&gt; GetAllCustomers();</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span> }</pre>
    

    Pretty basic. We have a Customer class somewhere and this interface describes a method called GetAllCustomers that will return you a list of Customer objects.

    With an interface you don’t have an implementation. There’s no code here to say where we get the customers from, just that we expect this to return us a list of them.

    Now in our code we can write something like this:

       1: public void DisplayAllCustomers(ICustomerService service)
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     <span style="color: #0000ff">foreach</span> (var customer <span style="color: #0000ff">in</span> service.GetAllCustomers())</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>         <span style="color: #008000">// Output whatever customer info here</span></pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>     }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span> }</pre>
    

    The method here expects an object that implements the ICustomerService interface. That’s how we can build and compile this but we have yet to build an implementation of this method. Of course the code won’t run because your application doesn’t know how to create an object that implements ICustomerService.

    Like I said, the implementation is up to you but you’ll probably be driving it from requirements or what the user needs to see or whatever. Here’s a sample implementation:

       1: internal class CustomerRepository : ICustomerService
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     <span style="color: #0000ff">public</span> IEnumerable&lt;Customer&gt; GetAllCustomers()</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>         <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> List&lt;Customer&gt;</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>                     {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>                         <span style="color: #0000ff">new</span> Customer {Name = <span style="color: #006080">&quot;Harold&quot;</span>}, </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>                         <span style="color: #0000ff">new</span> Customer {Name = <span style="color: #006080">&quot;Kumar&quot;</span>}</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span>                     };</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span>     }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11">  11:</span> }</pre>
    

    So if we created an object of this CustomerRepository class and passed it to the DisplayAllCustomers method above, we would output Harold and Kumar’s names (or whatever your display code was).

    The $10,000 Question

    People will stare at the code and say, why? Why create that ICustomerService and then have to go to the trouble of creating it and passing it along to the DisplayAllCustomers. More code to maintain they say. More work.

    Let’s try to dispel some myths here.

    Coding to Interfaces is Hard

    Really? Do you understand the code above? That’s coding to an interface. Could you do that yourself? Sure you can. Let’s move on.

    Coding to Interfaces Constrains Me

    It’s true. If you added the method “void AddCustomer(Customer customer)” to your inteface, you wouldn’t be able to compile your code. The CustomerRepostory class (and any other class that implemented the ICustomerService interface) would require it. Stop thinking about this as a constraint, it’s a design choice. It’s like the Architect giving you a window or door on the side of your house. You don’t go cutting open another hole because you want another window. You have to take into account load bearing walls, structural integrity, etc. which is what the Architect does (I know, I used to be one). Just because it looks good or you need it, doesn’t mean it should be done (at least in the way you might want it).

    Coding to Interfaces makes you do extra work

    Yes, you have to create those interfaces so yeah, that’s extra work. Some might argue that if your implementation is simple then you’re writing double the code. Again, all true. There are benefits that will outweigh this which we’ll look at in a moment.

    Where are the Benefits?

    Let’s talk some benefits here. First coding to an interface is giving you a layer of abstraction. Remember that ICustomerService above? The implementation is sort of silly but shows that we can write code that does what the system intends. We could also build an implementation that reads from a database. Or Active Directory. Or SAP. Or a Web Service. Each time we write a new implementation, we don’t have to change our DIsplayAllCustomers method.

    That’s abstraction. You don’t have to worry in your DisplayAllCustomers method where the data came from or what infrastructure may or may not exist. All you care about is that you expect a list of customers to come back.

    Now multiply that by 10 or 100 and you get the benefits of abstraction against a real codebase.

    Some people will talk about future proofing and interfaces and while that may be a benefit down the road, and it can happen, consider it icing on the cake. Imagine if you had coded to an IEnumerable interface instead of ArrayList? Now you *might* not have to rewrite a lot of code (or any if you’re really lucky).

    I do believe, and have rarely seen, entire implementations changed. For example one classic is the “build a database interface so we can swap between SQL and Oracle”. You build an abstraction over a database to make it simpler to code to but not necessarily swap out technologies.

    Just don’t use the future proofing claim as a crutch to not code to interfaces claiming YAGNI or something. There are different reasons for this.

    The other big thing is testing. Going back to our CustomerRepository. It’s an in-memory representation to a list of customers. Imagine you had additional methods on your interface like this:

       1: internal interface ICustomerService
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     IEnumerable&lt;Customer&gt; GetAllCustomers();</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     <span style="color: #0000ff">void</span> AddCustomer(Customer newCustomer);</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>     <span style="color: #0000ff">void</span> DeleteCustomer(Customer customerToDelete);</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span> }</pre>
    

    And now with your in-memory representation you can write tests that ensure items are added and deleted in your repository and the counts all match and the list comes back with the right names. Now you’re starting to test against your interface, which is a good thing.

    Testing

    Testing frameworks will let  you do things like create stubs or fake implementations of the interface, without actually writing code to return actual values. Without interfaces if you tried to test the AddCustomer method in say a SQL based implementation, you would need a database, login information, test data, etc. That’s great for infrastructure tests but for unit tests it’s a lot of overhead you shouldn’t be getting into.

    Another benefit is getting ahead of infrastructure. Imagine if your ICustomerService is going to talk to a web service, as web service that won’t be written for another month. You could go ahead and wait for the infrastructure to show up, code concrete classes against it, and then start your testing but now you’re in the crunch to get the system done and you’re just starting your unit testing.

    Instead, based on requirements and perhaps UI discussions with users using paper, whiteboard, or digital wireframes, you come up with the interface. “We’re going to need to display the customer fields and oh yeah, we want to search by first and last name”. Great. From that description you can come up with an interface something like this:

       1: interface ICustomerService
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     IEnumerable&lt;Customer&gt; FindBy(<span style="color: #0000ff">string</span> firstName);</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     IEnumerable&lt;Customer&gt; FindBy(<span style="color: #0000ff">string</span> firstName, <span style="color: #0000ff">string</span> lastName);</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span> }</pre>
    

    Again we can write up some implementation (maybe going against a preset list of names you import from a spreadsheet) and actually build out a working UI. The user can put their hands on it, search by names, and see the results returned. All without that pesky infrastructure. Then come the say the database gets built, you create your implementation to read it and do searches and BAM, your system is online and working end-to-end.

    On the testing front again, how would you test something that’s dependent on DateTime? For example you have a piece of code that ages some items in a system based on some business rules (or expires them).

    It’s all well and fine to start tossing around DateTime objects like this:

       1: public void ExpireTest(ICustomerService service, DateTime date)
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     <span style="color: #0000ff">foreach</span> (var customer <span style="color: #0000ff">in</span> service.GetAllCustomers())</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>         <span style="color: #0000ff">if</span>(customer.ContractDate &gt; date)</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>         {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>             ExpireContractFor(customer);</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>         }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span>     }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span> }</pre>
    

    However things get real ugly real fast. First I have to write this test and I’m sort of breaking both encapsulation and responsibility of the customer class. Maybe I should have a method on customer that takes in a DateTime object. Yuck. Now I’m passing that value into my business object which might be okay (it depends) but now consider the idea of something like this business rule:

       1: foreach (var customer in service.GetAllCustomers())
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     <span style="color: #0000ff">if</span>(customer.ContractDate.Day == date.Day &amp;&amp; date.Hour &gt; 12)</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>         ExpireContractFor(customer);</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>     }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span> }</pre>
    

    Now I’ll only expire the contract if the date passed in is the same day as my contract and it’s after noon. Silly logic yes, but would require another test method, another date object to be passed in, etc. A lot of setup to test something and then along comes this somewhere in my Customer class:

       1: class Customer
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> Name { get; set; }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>&#160; </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>     <span style="color: #0000ff">public</span> DateTime ContractDate { get; set; }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>&#160; </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span> AgeOfContract()</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>     {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span>         <span style="color: #0000ff">return</span> (<span style="color: #0000ff">int</span>) (DateTime.Now - ContractDate).TotalDays;</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span>     }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11">  11:</span> }</pre>
    

    Now I’m screwed, both in testing in code and testing on the site. I’m going to have to create test data with very specific dates, maybe mess around with the values (because I certainly can’t change the clock on the server) and frankly I’m going to cry.

    Interfaces can save you here. What if we had an interface called:

       1: interface IDateTime
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     DateTime Now { get; set; }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span> }</pre>
    

    And instead of the concrete implementation in our customer class we use the IDateTime interface. Here’s the Customer class refactored to use an interface:

       1: class Customer
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     <span style="color: #0000ff">readonly</span> IDateTime _dateTime;</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>&#160; </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>     Customer(IDateTime dateTime)</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>     {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>         _dateTime = dateTime;</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>     }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span>&#160; </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> Name { get; set; }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11">  11:</span>&#160; </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12">  12:</span>     <span style="color: #0000ff">public</span> IDateTime ContractDate { get; set; }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13">  13:</span>&#160; </pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14">  14:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span> AgeOfContract()</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum15">  15:</span>     {</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum16">  16:</span>         <span style="color: #0000ff">return</span> (<span style="color: #0000ff">int</span>) (_dateTime.Now - ContractDate).TotalDays;</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum17">  17:</span>     }</pre>
    
    <pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum18">  18:</span> }</pre>
    

    Yes, there’s more that needs to be here like how an IDateTime can subtract values from each other, return a TImeSpan object, etc. but this is just for concepts.

    With the interface added, I’m now abstracted away from the concrete implementation of DateTime hard coded into my Customer class. I’ll pass in something that might implement DateTime to return some real time but for testing I can set it to anything I want.

    Testing is easier now and I don’t have to change my domain logic to deal with responsibilities outside of my concerns.

    Interfaces vs. Classes is the kind of thing to start holy flame wars. Some argue it adds extra code/work to the developer, others claim it unnecessarily future-proofs your app (aka YAGNI) and others think it makes for easier testing and abstraction away from things that have yet to come.

    I like to live in the latter world where I build my systems loosely coupled but tightly integrated. Interfaces provide me that ability. I hope this article sheds some light on the subject for you, whatever you choose.

    Enjoy.

  • Visual Studio Achievements - Remember Kids They're Just For Fun

    I followed a neat project for the last couple of months which today became a reality, Visual Studio Achievements. Achievements are something the gaming world are very familiar with. They're milestones of recognition to meet like "Blowing up 30 Enemies with 1 Grenade" or "Destroy a Super Tank playing the Classic Game". There are a lot of sites around the Internet to track them including one dedicated to just XBox 360 ones here.

    They're fun and you get a bit of an internal high when you see this on your screen:

    The Visual Studio Achievements follows the same idea and, once installed, are based on your activity as you work. Achievements are measured and discovered in the background when you compile. And hey, it's cool and fun to see this after a compile:

    However when you look through the list of achievements one thing jumps out to those that try to follow good coding practices. These are certainly not that. In fact if I caught you writing a class with 10 levels of inheritance I would rip you a new one at the next daily stand up that would make even the likes of Gordon Ramsay shake in his knees.

    Ahh but you say these are for fun. Yes, yes they are and far from me to be the party pooper. What sparked me to write this blog response is to emphasize F-U-N and not practice. Seriously you won't believe (or maybe you will) how many developers I talked to around me that thought this was a cool thing to install in their work environment.

    Wait. Let's think about this for a minute.

    1. Install achievemnts add-on in work environment.
    2. Do work
    3. Get achievment

    Okay, the first step is fine. The second step is what we do. The third step? Hang on. Didn't I just say that having 10 levels of inheritance is a bad thing? So if you get the achievement during your daily work it should be a *bad* thing, not something to celebrate.

    It's like breaking the build (which we all do at some point and certainly people get ridiculed for it, it's all fun right). Breaking the build is a bad thing but it's a good spin. It means we recognize something went wrong and whatever mechanism you have to let you know (since everyone on the team should get notified) means you get up, rally around, and fix the problem. Good stuff. Build fixed, work continues.

    Where's the rallying here? The only thing that will happen is the dev will see the achievement, pat himself on the back and have a chuckle then what? What *should* happen if you installed this and got an achievment should be:

    1. Do work
    2. Get achievement
    3. Chuckle
    4. Silently say "Oh shit"
    5. Fix problem
    6. Lather, Rinse, Repeat

    Hopefully this is the case, but again I've asked a few people and they miss the point of the fun aspect here. This shouldn't be something you strive to achieve, the achievements here (as they stand currently) should be something to avoid. In fact it should set of an internal whoop-whoop alarm and cause you to think "What the Hell was I thinking".

    Before you dismiss me, I'm all for fun. I'm the guy that has robot zombies and posters of Close Encounters in my cubicle and challenges developers to games of magnetic Angry Birds after stand-up. I'm all that. However I just want people to be aware that this is fun and there might be a message here. Keep focused on good practices and not bad ones. In the game achievement world, we *try* to achieve these tasks. Heck when I get a game and I'm bored I look through the achievements and set myself up to try to accomplish it (mostly failing since I literally suck at almost every game).

    However developers should not be looking at these achievements as something they should be striving for (except just to get the achievement and make it onto the site). What would I really like to see? Some actual achievements that developers can strive for and be proud to achieve. How about "Eliminate 10% of the codebase without removing functionality" or "Mock a service and pass 10 unit tests against it" as achievements.

    Herein lies the real problem though. Getting the *fun* achievements is easy. They're tangible and simple to measure. How do you measure "good code"? Can you scan code with a computer and determine separation of concern? Or if your code follows SOLID principles or not? Somethings are detectable but most of the good stuff is not. That's the real trick here (and if you figure it out in a system where you can automatically detect it and award and achievment for, all the better).

    Like I said, have fun with this addon. It's neat and I applaud the developers for coming up with it. I don't discourage its use but keep in mind what it is and what the message behind it is. Hopefully one day with might have some positive achievements to strive for as well as the fun ones.

  • Some JSON Resources For You

    As a developer I really dig JSON over XML for information exchange. It's clean, simple, and just works. I don't have to deal with complicated schema validation, reams of unreadable encoded text, and hierarchies that make no sense. I prefer to consume in apps and more and more services offer it up natively these days. Here are a few key tools I use that you might fun value-add in your dealings with JSON.

    Hmm... is it JSON or Json? Anyway, here's a short list.

    Json.NET

    IMHO this is the key library for working with JSON. Yes, you can do some native de-serialization with .NET but the Json.NET library makes reading and writing JSON easy. You can de-serialize a JSON response with one line of code and suck it into a set of C# classes (or use the JObject class itself to pluck values out directly). If you're really hung up on the angle brackets, Json.NET can translate your JSON to and from XML (but that would be silly). Highly recommended and it even comes as a Nuget package so nothing to download and unzip!

    JSON Format

    Getting JSON and trying to look at it can be painful. Sure, it's a human readable format but sometimes it comes as a big gobbly-gook glob of text if the API returns your data with the whitespace compressed (to reduce the size of the package). This online tool lets you paste in a JSON string and reformat it into something more readable. Bonus feature is you can just plug in a URL that returns the data in JSON format as well. Handy.

    JSON C# Class Generator

    Of course if you consume JSON with the Json.NET library one very slick feature is a single line of code to de-serialize it into a C# class. Here's an example:

    var records = JsonConvert.DeserializeObject<RecordModel>(someDownloadedString);

    The variable "records" will now be a complete object graph of your JSON (including child objects de-serialized into arrays, lists, or whatever your collection type is). For this to work you need some classes of course. They're simple to write and are just POCO but do have to match up with the structure of the JSON so it can be tricky creating them and a tiresome task.

    Enter the JSON C# Class Generator project. This is a GUI tool that you plunk your JSON into, set some properties and generate a series of C# classes you can link into your project and perform the online-line-de-serialization above. Pretty nice and supports a lot of features plus it's open source to boot.

    json2csharp

    Going one step better (or worse depending on your point of view) is the online version of a similar tool. With the json2csharp site, you can either enter the JSON data directly or enter the URL and it'll fetch it for you. The class generation is simple (as it should be) with no options but it's nice as you don't have to download/install anything. I did find a few JSON APIs that didn't work with this one but did work with the formatter so in that case I had to enter the URL in the formatter to get the JSON, then plunk the data into this tool to get my classes. In any case, it's way better to use tools like these rather than writing the classes yourself (again, my opinion, your mileage may vary).

    JSONView

    If you're using JSON and looking for a quick hit to see your data, look no further than JSONView, a Firefox add-on that will format the JSON data output for you. Once installed, just visit the URL to your JSON data and the output will render in the browser. That's as simple as it can get. No mess, no fuss.

    Shameless Plug

    There are a lot of tutorials out there on using some of these tools, including one shameless plug of my own. Here's a blog entry I wrote on consuming MediaWiki's content in JSON format. MediaWiki is the software powering Wikipedia (along with a ton of other wiki sites). It walks through using the Json.NET library and navigating around Wikipedia using the data in JSON created classes.

    Got more resources? Post them in the comments if you have some other JSON related resources and I'll update the post with them. Until then, enjoy!

  • Prairie Dev Con West - Sessions Announced and Registration Open!

    I’m thrilled to announce that the Prairie Dev Con West folks have posted sessions and speakers on their site, and opened registration for Prairie Developer Conference West!

    Three Days of Fantastic Sessions!
    Prairie Dev Con West happens March 13 – 15, and will be three days of software development, IT Pro, and Agile sessions delivered by world class speakers and experts in the technical industry! We’ve currently posted 45 of the 72 sessions we’ll be providing, so check out what’s on the site and check back over the next few weeks as we fill out the session list!

    Carl Franklin and Richard Campbell’s .NET Rocks Show LIVE at Prairie Dev Con!
    We’re excited to have Carl Franklin and Richard Campbell attend the conference! They’ll be presenting sessions, but also doing an episode of their .NET Rocks internet show live from the conference!



    Pre Conference Workshops!
    We have two pre-conference workshops happening on Monday, March 12th! Dylan Smith will be doing a full day on “Creating Powerful Build and Deploy Processes with TFS Build” and Bil Simser will be doing “Windows Phone 7 Developer Workshop”! Both of these guys are respected experts in their field and we’re very proud to be able to offer these workshops.

    Attending either workshop is $399.99, but you can get 50% off if you bundle a workshop with a conference registration!

    Early Bird Pricing!
    Registration is now open! For the month of December you can register at our early bird price of $499.99, which is $300 off the regular price! Also, groups of 3 or more get an additional $50 off each registration!

    You can register online or request an invoice.

    Hotel and Venue!
    The conference will be held at the TELUS Convention Centre, and the official conference hotel is the Calgary Marriott right next door! We have a limited number of hotel rooms at a conference rate of $209.00 a night, so book your hotel accommodations early! Call 1-800-896-6878 and mention Prairie Developer Conference when booking.

    Keep In Touch!
    Please let me know if you have any questions or comments! There’s many ways to connect with the conference and receive announcements/updates:

    Join us!
    Prairie Dev Con West will be *the* technology event to attend in Alberta in 2012! In addition to the three days of fantastic sessions by amazing speakers, there are a number of community events being planned the week of the conference! You’ll definitely want to be in Calgary this March to be part of it!

  • Using the Builder Pattern To Create SharePoint Lists

    In building out a custom solution I get tired of writing procedural code to create a list, add the columns, setup the views, and add some initial data. Many moons ago I decided to follow a creational design pattern called the Builder pattern. This pattern separates the construction of a complex object from it’s representation so that the same process can create different representations. Basically, let’s build a bunch of custom lists using OO instead of repetitive procedural-like code. Here’s how.

    First let’s take a look at the Builder pattern. Here it in UML form for visual dudes:

    Builder

    Pretty straight forward. The principle here is that all concrete objects will adhere to a contract (the Builder) and implement the specific way they need to build things while the Director handles the correct sequence of object creation.

    This suites Lists pretty nicely in SharePoint. A list needs to be created via the SPWeb it lives in, it needs fields added to it, views setup, and items added to the finished list.

    Okay, time for some code.

    First here’s our abstract ListBuilder. All implementations of creating a new list will inherit from this. It provides abstract methods that make up all the parts of a list (fields, views, items, and the list itself).

    public abstract class ListBuilder
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>{</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    <span style="color: rgb(0, 0, 255);">protected</span> SPList TheList {get; set;}</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">abstract</span> <span style="color: rgb(0, 0, 255);">void</span> CreateList(SPWeb web);</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">abstract</span> <span style="color: rgb(0, 0, 255);">void</span> CreateFields();</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">abstract</span> <span style="color: rgb(0, 0, 255);">void</span> CreateViews();</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">abstract</span> <span style="color: rgb(0, 0, 255);">void</span> AddInitialData();</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">abstract</span> <span style="color: rgb(0, 0, 255);">void</span> DeleteList(SPWeb web);</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>}</pre>
    

    Pretty basic stuff. We have methods to create and delete the list (which requires the SPWeb object it belongs to) and there’s methods for creating fields and views and adding some initial data (for example if you have a lookup list you’re creating and you want to seed it with some initial values).

    There’s also a protected property called TheList which holds an instance of the list created. This is for adding fields and views later in the construction process. P.S. Personally I hate the property name “TheList” but “List” gets all confused with System.Generic.List types and SPList is already a SharePoint type so to avoid conflicts I picked this. I’m also lazy and didn’t want to call it SharePointList or something. Feel free to make it whatever you want.

    Now that we have our abstract ListBuilder let’s create the ListDirector. This class will handle building the list by orchestrating the assembly of the pieces. It also provides outside access to create and delete the lists (which we’ll call from our feature activating/deactivating).

    public class ListDirector
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>{</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    <span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">readonly</span> SPWeb _web;</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'> </pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    <span style="color: rgb(0, 0, 255);">public</span> ListDirector(SPWeb web)</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    {</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>        _web = web;</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    }</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'> </pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">void</span> CreateUsing(ListBuilder builder)</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    {</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>        builder.CreateList(_web);</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>        builder.CreateFields();</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>        builder.CreateViews();</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>        builder.AddInitialData();</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    }</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'> </pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">void</span> DeleteUsing(ListBuilder builder)</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    {</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>        builder.Delete(_web);</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    }</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>}</pre>
    

    The ListDirector is created using the SPWeb object (so it can tell the list builder where to create/delete lists from) and knows the order to put the pieces of the list together. This way ListBuilder (and any classes inheriting from it) don’t need to know how to orchestrate the pieces and can just work independently. You can also create special ListDirectors that do things like update lists (avoid the creation) or append data.

    Armed with our abstract class and our director we head down the path of actually creating a specific list. For this sample we’ll do something really simple. A lookup list for countries and contains a name we’ll use for picking items and some internal codes for each item.

    First we’ll start with the bare bones builder:

    public class CountryListBuilder : ListBuilder
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>{</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> CreateList(SPWeb web)</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    {</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    }</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>&nbsp;</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> CreateFields()</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    {</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    }</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>&nbsp;</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> CreateViews()</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    {</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    }</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>&nbsp;</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> AddInitialData()</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    {</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    }</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>&nbsp;</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    <span style="color: rgb(0, 0, 255);">public</span> <span style="color: rgb(0, 0, 255);">override</span> <span style="color: rgb(0, 0, 255);">void</span> DeleteList(SPWeb web)</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    {</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    }</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>}</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>&nbsp;</pre>
    

    Now let’s look at each method in detail. There’s not a lot here to see because our list builder should be lightweight. Of course this completely depends on your needs so you might have something with 30 fields but the ListBuilder class should simplify things and remove redundancies for you.

    First we’ll create the list. To do this we need the SPWeb object which we’ll pass in.

    public override void CreateList(SPWeb web)
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>{</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    var id = web.Lists.Add(<span style="color: rgb(0, 96, 128);">"Countries"</span>, <span style="color: rgb(0, 96, 128);">"Country lookup list"</span>, SPListTemplateType.GenericList);</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    TheList = web.Lists[id];</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    TheList.OnQuickLaunch = <span style="color: rgb(0, 0, 255);">true</span>;</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    TheList.Update();</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>}</pre>
    

    Here we create a generic list, retrieve it, and update the metadata (in this case if it’s on the Quick Launch or not, but you could do things like setting the Title or other values. The call to Update() is only needed to update the metadata. If all you’re doing is adding the list then the first line is all you need.

    Next we’ll add our additional fields:

    public override void CreateFields()
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>{</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    TheList.Fields.Add(<span style="color: rgb(0, 96, 128);">"Code"</span>, SPFieldType.Text, <span style="color: rgb(0, 0, 255);">true</span>);</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    TheList.Fields.Add(<span style="color: rgb(0, 96, 128);">"Currency"</span>, SPFieldType.Text, <span style="color: rgb(0, 0, 255);">true</span>);</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>}</pre>
    

    Since we’re creating this list from a generic (custom) list we already have a title field. Here we add two new fields.

    Next up is the views.

    public override void CreateViews()
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>{</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    var defaultView = TheList.Views[0];</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    view.ViewFields.Add(<span style="color: rgb(0, 96, 128);">"Code"</span>);</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    view.ViewFields.Add(<span style="color: rgb(0, 96, 128);">"Currency"</span>);</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    view.Update();</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>}</pre>
    

    When a list is created a default view is created that contains the Title field. Here we grab that view then add our two custom fields to it. You could also do all kinds of things with the view like setting the sort order, adding filters or creating entirely new views.

    Finally we want to seed our list with some initial data so every time our feature is activated we have some data for it.

    public override void AddInitialData()
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>{</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    addItem(<span style="color: rgb(0, 96, 128);">"Canada"</span>, <span style="color: rgb(0, 96, 128);">"CAN"</span>, <span style="color: rgb(0, 96, 128);">"CDN"</span>);</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    addItem(<span style="color: rgb(0, 96, 128);">"United States"</span>, <span style="color: rgb(0, 96, 128);">"US"</span>, <span style="color: rgb(0, 96, 128);">"USD"</span>);</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>}</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>&nbsp;</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">void</span> addItem(<span style="color: rgb(0, 0, 255);">string</span> title, <span style="color: rgb(0, 0, 255);">string</span> code, <span style="color: rgb(0, 0, 255);">string</span> currency)</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>{</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    var item = TheList.Items.Add();</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    item[<span style="color: rgb(0, 96, 128);">"Title"</span>] = title;</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    item[<span style="color: rgb(0, 96, 128);">"Code"</span>] = code;</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    item[<span style="color: rgb(0, 96, 128);">"Currency"</span>] = currency;</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    item.Update();</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>}</pre>
    

    Here we have a helper to add an item to the list. Adding an item requires a few steps (creating the SPItem via Add, setting the data, calling update) so it’s wrapped in a method in the class.

    You might be balking at the use of hard coded values and field names and whatnot here. That’s fine. You could go ahead and assign those to constants inside the class. The point is that the field names are all contained within this one class so if you ever wanted to change them you only have to change the values here. Create constants for the field name might be a good idea too. You could also do something like read from a text or xml file in your AddInitialData method if you had a lot of data to seed (or even pull it from a resource file in the assembly).

    Now we have all the parts to build up the list. Let’s call it in a feature. As we move up the ladder and away from our list builder things get dead simple. Here’s the code we have to activate the feature:

    public override void FeatureActivated(SPFeatureReceiverProperties properties)
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>{</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    <span style="color: rgb(0, 0, 255);">using</span>(var web = properties.Feature.Parent <span style="color: rgb(0, 0, 255);">as</span> SPWeb)</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    {</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>        var director = <span style="color: rgb(0, 0, 255);">new</span> ListDirector(web);</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>        director.CreateUsing(<span style="color: rgb(0, 0, 255);">new</span> CountryListBuilder());</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    }</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>}</pre>
    

    Like I said. Dead simple. We pass the SPWeb object to the director (who will internally pass it along to the ListBuilder as needed) and we call the CreateUsing method passing it a new CountryListBuilder.

    If we want to add new lists all we have to do is this:

    1. Create a new ListBuilder class inheriting from ListBuilder
    2. Fill in the abstract methods
    3. Add a new CreateUsing call in our FeatureActivated method
    4. Deploy

    Cool huh?

    Okay, so we have it build but what about getting rid of it? Just as easy.

    First we need to finish our CountryListBuilder. There’s one more method we need to implement:

    public override void DeleteList(SPWeb web)
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>{</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    var id = web.Lists[<span style="color: rgb(0, 96, 128);">"Countries"</span>].ID;</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    web.Lists.Delete(id);</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>}</pre>
    

    Now to finish off we just implement the FeatureDeactivating method:

    public ovveride void FeatureDeactivating(SPFeatureReceiverProperties properties)
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>{</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    <span style="color: rgb(0, 0, 255);">using</span>(var web = properties.Feature.Parent <span style="color: rgb(0, 0, 255);">as</span> SPWeb)</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>    {</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>        var director = <span style="color: rgb(0, 0, 255);">new</span> ListDirector(web);</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>        director.DeleteUsing(<span style="color: rgb(0, 0, 255);">new</span> CountryListBuilder());</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: white;'>    }</pre>
    
    <pre style='margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: "Courier New", courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);'>}</pre>
    

    Just reverse of activating we call the DeleteUsing method on the director passing it a CountryListBuilder object. We really don’t have to keep the variable around and there’s little cost to creating a new object to pass it. There’s nothing unique that we have to keep around from creation. The CountryListBuilder class is just there to provide us the interace to it’s methods.

    You might be thinking why do all this? Why don’t I just create the ListBuilder class and call the methods directly. Like I said, the Director abstracts away all the co-ordination you need to build the list while the list knows how to build its parts, it doesn’t necessarily know how to construct itself. This is done for reason. Maybe you want to build the list up differently depending on the environment. Or maybe you have a Director to handle creating items from scratch and another director for updating existing data (say in the Feature Upgrading event with a production site). The same pattern and classes apply, there are just different implementations to create. Also with the abstraction the ListDirector and ListBuilder provides, the code you have to maintain (and debug) in the Feature events is next to nothing and any errors can happen and be handled down where they need to be, not have to bubble up to the feature (remember you have no UI in the feature events).

    So that’s it. Now I just have to create a new class for each List I want to build, inherit from ListBuilder and just add one line of code to my Feature activating/deactiving. Pretty clean and pretty quick to get up and running.

    This is just *one* way of doing this. You could use other patterns that might be more appropriate (the Abstract Factory or perhaps Prototype comes to mind) but this is the one I went with and it works pretty good for me so far. Fields are more complex beasts so my CreateFields() method is sort of doing double duty by adding fields and also updating existing ones (or new ones) by setting the field lengths. This could be split out to say two methods (CreateFields and UpdateFields) or even a FieldBuilder class could be created and handled by the ListBuilder (who would act as the Director) but maybe that’s over complicating things.

    I’m sure there are a lot of things that could be better in this code. Interface vs. abstract class; passing in the SPWeb as a constructor to the ListBuilder; etc. And yes, there’s no exception handling, logging, or backout in case things fail here. What if someone renamed the list? What if the list doesn’t exist when the feature is deactivated? Hey guys, it’s a blog post, not production code. Feel free however to comment and suggest improvements and alternate ideas.

    Hope this helps! Happy coding.

  • Secret Agent Man

    Just a quick one this morning as we all get started in the week. Something that comes into play (sometimes in a big way) is the user agent string your browser gives off. So for example using the User-Agent field in the request header, you can determine what browser the user is running and act accordingly.

    Internet Explorer 9 modified the UA string slightly so just in case you're looking for it here are the user agent strings for IE9 (in various modes):

    • Internet Explorer 9 Mode: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
    • Internet Explorer 8 Mode: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; MS-RTC LM 8; InfoPath.3; .NET4.0C; .NET4.0E; Zune 4.7)
    • Internet Explorer 7 Mode: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; MS-RTC LM 8; InfoPath.3; .NET4.0C; .NET4.0E; Zune 4.7)
    • Internet Explorer 9 (Compatibility Mode): Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; MS-RTC LM 8; InfoPath.3; .NET4.0C; .NET4.0E; Zune 4.7)

    A couple of things to note here:

    • This was from a 64-bit Windows 7 client so that might account for the WOW64 in the agent string (I don't have a 32-bit client to test from)
    • Various applications and platforms add to the UA string just like they do in previous IE releases. So for example you can see I have various .NET versions installed as well as Zune. You can take advantage of this by querying the UA string for compatibilities and present options accordingly to the end user.
    • As applications will continue to add and modify this string you'll want to query the string for parts not the entire string. For example if you want to detect if you're coming from IE running  on a Windows Phone 7 just look for "iemobile" in the user agent string

    Happy hacking!

  • Imperative vs. LINQ Performance on WP7

    Jesse Liberty had a nice post presenting the concepts around imperative, LINQ and fluent programming to populate a listbox. Check out the post as it’s a great example of some foundational things every .NET programmer should know.

    I was more interested in what the IL code that would be generated from imperative vs. LINQ was like and what the performance numbers are and how they differ.

    The code at the instruction level is interesting but not surprising. The imperative example with it’s creating lists and loops weighs in at about 60 instructions.

       1:  .method private hidebysig instance void ImperativeMethod() cil managed
       2:  {
       3:      .maxstack 3
       4:      .locals init (
       5:          [0] class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> someData,
       6:          [1] class [mscorlib]System.Collections.Generic.List`1<int32> inLoop,
       7:          [2] int32 n,
       8:          [3] class [mscorlib]System.Collections.Generic.IEnumerator`1<int32> CS$5$0000,
       9:          [4] bool CS$4$0001)
      10:      L_0000: nop 
      11:      L_0001: ldc.i4.1 
      12:      L_0002: ldc.i4.s 50
      13:      L_0004: call class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> [System.Core]System.Linq.Enumerable::Range(int32, int32)
      14:      L_0009: stloc.0 
      15:      L_000a: newobj instance void [mscorlib]System.Collections.Generic.List`1<int32>::.ctor()
      16:      L_000f: stloc.1 
      17:      L_0010: nop 
      18:      L_0011: ldloc.0 
      19:      L_0012: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> [mscorlib]System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator()
      20:      L_0017: stloc.3 
      21:      L_0018: br.s L_003a
      22:      L_001a: ldloc.3 
      23:      L_001b: callvirt instance !0 [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current()
      24:      L_0020: stloc.2 
      25:      L_0021: nop 
      26:      L_0022: ldloc.2 
      27:      L_0023: ldc.i4.5 
      28:      L_0024: cgt 
      29:      L_0026: ldc.i4.0 
      30:      L_0027: ceq 
      31:      L_0029: stloc.s CS$4$0001
      32:      L_002b: ldloc.s CS$4$0001
      33:      L_002d: brtrue.s L_0039
      34:      L_002f: ldloc.1 
      35:      L_0030: ldloc.2 
      36:      L_0031: ldloc.2 
      37:      L_0032: mul 
      38:      L_0033: callvirt instance void [mscorlib]System.Collections.Generic.List`1<int32>::Add(!0)
      39:      L_0038: nop 
      40:      L_0039: nop 
      41:      L_003a: ldloc.3 
      42:      L_003b: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()
      43:      L_0040: stloc.s CS$4$0001
      44:      L_0042: ldloc.s CS$4$0001
      45:      L_0044: brtrue.s L_001a
      46:      L_0046: leave.s L_005a
      47:      L_0048: ldloc.3 
      48:      L_0049: ldnull 
      49:      L_004a: ceq 
      50:      L_004c: stloc.s CS$4$0001
      51:      L_004e: ldloc.s CS$4$0001
      52:      L_0050: brtrue.s L_0059
      53:      L_0052: ldloc.3 
      54:      L_0053: callvirt instance void [mscorlib]System.IDisposable::Dispose()
      55:      L_0058: nop 
      56:      L_0059: endfinally 
      57:      L_005a: nop 
      58:      L_005b: ldarg.0 
      59:      L_005c: ldfld class [System.Windows]System.Windows.Controls.ListBox PerfTest.MainPage::LB1
      60:      L_0061: ldloc.1 
      61:      L_0062: callvirt instance void [System.Windows]System.Windows.Controls.ItemsControl::set_ItemsSource(class [mscorlib]System.Collections.IEnumerable)
      62:      L_0067: nop 
      63:      L_0068: ret 
      64:      .try L_0018 to L_0048 finally handler L_0048 to L_005a
      65:  }
      66:   
      67:   

    Compare that to the IL generated for the LINQ version which has about half of the instructions and just gets the job done, no fluff.

       1:  .method private hidebysig instance void LINQMethod() cil managed
       2:  {
       3:      .maxstack 4
       4:      .locals init (
       5:          [0] class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> someData,
       6:          [1] class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> queryResult)
       7:      L_0000: nop 
       8:      L_0001: ldc.i4.1 
       9:      L_0002: ldc.i4.s 50
      10:      L_0004: call class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> [System.Core]System.Linq.Enumerable::Range(int32, int32)
      11:      L_0009: stloc.0 
      12:      L_000a: ldloc.0 
      13:      L_000b: ldsfld class [System.Core]System.Func`2<int32, bool> PerfTest.MainPage::CS$<>9__CachedAnonymousMethodDelegate6
      14:      L_0010: brtrue.s L_0025
      15:      L_0012: ldnull 
      16:      L_0013: ldftn bool PerfTest.MainPage::<LINQProgramming>b__4(int32)
      17:      L_0019: newobj instance void [System.Core]System.Func`2<int32, bool>::.ctor(object, native int)
      18:      L_001e: stsfld class [System.Core]System.Func`2<int32, bool> PerfTest.MainPage::CS$<>9__CachedAnonymousMethodDelegate6
      19:      L_0023: br.s L_0025
      20:      L_0025: ldsfld class [System.Core]System.Func`2<int32, bool> PerfTest.MainPage::CS$<>9__CachedAnonymousMethodDelegate6
      21:      L_002a: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0> [System.Core]System.Linq.Enumerable::Where<int32>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>, class [System.Core]System.Func`2<!!0, bool>)
      22:      L_002f: ldsfld class [System.Core]System.Func`2<int32, int32> PerfTest.MainPage::CS$<>9__CachedAnonymousMethodDelegate7
      23:      L_0034: brtrue.s L_0049
      24:      L_0036: ldnull 
      25:      L_0037: ldftn int32 PerfTest.MainPage::<LINQProgramming>b__5(int32)
      26:      L_003d: newobj instance void [System.Core]System.Func`2<int32, int32>::.ctor(object, native int)
      27:      L_0042: stsfld class [System.Core]System.Func`2<int32, int32> PerfTest.MainPage::CS$<>9__CachedAnonymousMethodDelegate7
      28:      L_0047: br.s L_0049
      29:      L_0049: ldsfld class [System.Core]System.Func`2<int32, int32> PerfTest.MainPage::CS$<>9__CachedAnonymousMethodDelegate7
      30:      L_004e: call class [mscorlib]System.Collections.Generic.IEnumerable`1<!!1> [System.Core]System.Linq.Enumerable::Select<int32, int32>(class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>, class [System.Core]System.Func`2<!!0, !!1>)
      31:      L_0053: stloc.1 
      32:      L_0054: ldarg.0 
      33:      L_0055: ldfld class [System.Windows]System.Windows.Controls.ListBox PerfTest.MainPage::LB2
      34:      L_005a: ldloc.1 
      35:      L_005b: callvirt instance void [System.Windows]System.Windows.Controls.ItemsControl::set_ItemsSource(class [mscorlib]System.Collections.IEnumerable)
      36:      L_0060: nop 
      37:      L_0061: ret 
      38:  }

    Again, not surprising here but a good indicator that you should consider using LINQ where possible. In fact if you have ReSharper installed you’ll see a squiggly (technical term) in the imperative code that says “Hey Dude, I can convert this to LINQ if you want to be c00L!” (or something like that, it’s the 2010 geek version of Clippy).

    What about the fluent version? As Jon correctly pointed out in the comments, when you compare the IL for the LINQ code and the IL for the fluent code it’s the same. LINQ and the fluent interface are just syntactical sugar so you decide what you’re most comfortable with. At the end of the day they’re both the same.

    Now onto the numbers. Again I expected the imperative version to be better performing than the LINQ version (before I saw the IL that was generated). Call it womanly instinct. A gut feel. Whatever. Some of the numbers are interesting though.

    For Jesse’s example of 50 items, the numbers were interesting. The imperative sample clocked in at 7ms while the LINQ version completed in 4. As the number of items went up, the elapsed time didn’t necessarily climb exponentially. At 500 items they were pretty much the same and the results were similar up to about 50,000 items. After that I tried 500,000 items where the gap widened but not by much (2.2 seconds for imperative, 2.3 for LINQ). It wasn’t until I tried 5,000,000 items where things were noticeable. Imperative filled the list in 20 seconds while LINQ took 8 seconds longer (although personally I wouldn’t suggest you put 5 million items in a list unless you want your users showing up at your door with torches and pitchforks).

    Here’s the table with the full results.

      </STRONG><TD vAlign="top" width="71"><STRONG>50</STRONG></TD><STRONG>
    
      </STRONG><TD vAlign="top" width="71"><STRONG>500</STRONG></TD><STRONG>
    
      </STRONG><TD vAlign="top" width="71"><STRONG>5,000</STRONG></TD><STRONG>
    
      </STRONG><TD vAlign="top" width="71"><STRONG>50,000</STRONG></TD><STRONG>
    
      </STRONG><TD vAlign="top" width="71"><STRONG>500,000</STRONG></TD><STRONG>
    
      </STRONG><TD vAlign="top" width="71"><STRONG>5,000,000</STRONG></TD>
    </TR>
    
    <TR>
      <TD vAlign="top" width="71">Imperative</TD>
    
      <TD vAlign="top" width="71">7ms</TD>
    
      <TD vAlign="top" width="71">7ms</TD>
    
      <TD vAlign="top" width="71">38ms</TD>
    
      <TD vAlign="top" width="71">223ms</TD>
    
      <TD vAlign="top" width="71">2230ms</TD>
    
      <TD vAlign="top" width="71">20974ms</TD>
    </TR>
    
    <TR>
      <TD vAlign="top" width="71">LINQ/Fluent</TD>
    
      <TD vAlign="top" width="71">4ms</TD>
    
      <TD vAlign="top" width="71">6ms</TD>
    
      <TD vAlign="top" width="71">41ms</TD>
    
      <TD vAlign="top" width="71">240ms</TD>
    
      <TD vAlign="top" width="71">2310ms</TD>
    
      <TD vAlign="top" width="71">28731ms</TD>
    </TR>
    
    Method/Items

    Like I said, at the end of the day it’s not a huge difference and you really don’t want your users waiting around for 30 seconds on a mobile device filling lists. In fact if Windows Phone 7 detects you’re taking more than 10 seconds to do any one thing, it considers the app hung and shuts it down. The results here are for Windows Phone 7 but frankly they're the same for desktop and web apps so feel free to apply it generally.

    From a programming perspective, choose what you like. Some LINQ statements can get pretty hairy so I usually fall back with my simple mind and write it imperatively. If you really want to impress your friends, write it old school then let ReSharper do the hard work for!

    Happy programming!

  • Generic Pop and Push for List<T>

    Here's a little snippet I use to extend a generic List class to have similar capabilites to the Stack class.

    The Stack<T> class is great but it lives in its own world under System.Object. Wouldn't it be nice to have a List<T> that could do the same? Here's the code:

       1:  public static class ExtensionMethods
       2:  {
       3:      public static T Pop<T>(this List<T> theList)
       4:      {
       5:          var local = theList[theList.Count - 1];
       6:          theList.RemoveAt(theList.Count - 1);
       7:          return local;
       8:      }
       9:   
      10:      public static void Push<T>(this List<T> theList, T item)
      11:      {
      12:          theList.Add(item);
      13:      }
      14:  }

    It's a simple extension but I've found it useful, hopefully you will too! Enjoy.

  • Dotfuscator Deep Dive with WP7

    I thought I would share some experience with code obfuscation (specifically the Dotfuscator product) and Windows Phone 7 apps. These days twitter is a buzz with black hat and white operations coming out about how the marketplace is insecure and Microsoft failed, blah, blah, blah. So it’s that much more important to protect your intellectual property. You should protect it no matter what when releasing apps into the wild but more so when someone is paying for them. You want to protect the time and effort that went into your code and have some comfort that the casual hacker isn’t going to usurp your next best thing.

    DataObfuscation

    Enter code obfuscation. Code obfuscation is one tool that can help protect your IP. Basically it goes into your compiled assemblies, rewrites things at an IL level (like renaming methods and classes and hiding logic flow) and rewrites it back so that the assembly or executable is still fully functional but prying eyes using a tool like ILDASM or Reflector can’t see what’s going on.  You can read more about code obfuscation here on Wikipedia.

    A word to the wise. Code obfuscation isn’t 100% secure. More so on the WP7 platform where the OS expects certain things to be as they were meant to be. So don’t expect 100% obfuscation of every class and every method and every property. It’s just not going to happen. What this does do is give you some level of protection but don’t put all your eggs in one basket and call it done. Like I said, this is just one step in the process.

    There are a few tools out there that provide code obfuscation and support the Windows Phone 7 platform (see links to other tools at the end of this post). One such tool is Dotfuscator from PreEmptive solutions. The thing about Dotfuscator is that they’ve struck a deal with Microsoft to provide a *free* copy of their commercial product for Windows Phone 7. The only drawback is that it only runs until March 31, 2010. However it’s a good place to start and the focus of this article.

    Getting Started

    When you fire up Dotfuscator you’re presented with a dialog to start a new project or load a previous one. We’ll start with a new project. You’re then looking at a somewhat blank screen that shows an Input tab (among others) and you’re probably wondering what to do?

    image

    Click on the folder icon (first one) and browse to where your xap file is. At this point you can save the project and click on the arrow to start the process.

    image

    Bam! You’re done. Right? Think again. The program did indeed run and create a new version of your xap (doing it’s thing and rewriting back your *obfuscated* assemblies) but let’s take a look at the assembly in Reflector to see the end result.

    Remember a xap file is really just a glorified zip file (or cab file if you prefer). When you ran Dotfuscator for the first time with the default settings you’ll see it created a new version of your xap in a folder under “My Documents” called “Dotfuscated” (you can configure the output directory in settings). Here’s the new xap file.

    image

    Since a xap is just a zip, rename it to .cab or .zip or something and open it with your favorite unarchive program (I use WinRar but it doesn’t matter as long as it can unzip files). If you already have the xap file associated with your unarchive tool the rename isn’t needed. Once renamed extract the contents of the xap to your hard drive:

    image

    Now you’ll have a folder with the contents of the xap file extracted:

    image

    Double click or load up your assembly (WindowsPhoneDataBoundApplication1.dll in the example) in Reflector and let’s see the results:

    image

    Hmm. That doesn’t look right. I can see all the methods and the code is all there for my LoadData method I wanted to protect. Product failure. Let’s return it for a refund.

    Hold your horses. We need to check out the settings in the program first. Remember when we loaded up our xap file. It started us on the Input tab but there was a settings tab before that. Wonder what it does? Here’s the default settings:

    image

    Renaming

    Taking a closer look, all of the settings in Feature are disabled. WTF? Yeah, it leaves me scratching my head why an obfuscator by default doesn’t obfuscate. However it’s a simple fix to change these settings. Let’s enable Renaming as it sounds like a good start. Renaming obscures code by renaming methods and fields to names that are not understandable.

    image

    Great. Run the tool again and go through the process of unzipping the updated xap and let’s take a look in Reflector again at our project.

    image

    This looks a lot better. Lots of methods named a, b, c, d, etc. That’ll help slow hackers down a bit. What about our logic that we spent days weeks on? Let’s take a look at the LoadData method:

    image

    What gives? We have renaming enabled but all of our code is still there. If you look through all your methods you’ll find it’s still sitting there out in the open.

    Control Flow

    Back to the settings page again. Let’s enable Control Flow now. Control Flow obfuscation synthesizes branching, conditional, and iterative constructs (such as if, for, and while) that produce valid executable logic, but yield non-deterministic semantic results when decompilation is attempted. In other words, the code runs as before, but decompilers cannot reproduce the original code.

    image

    Do the dance again and let’s see the results in Reflector.

    image

    Ahh, that’s better. Methods renamed *and* nobody can look at our LoadData method now. Life is good.

    More than Minimum

    This is the bare minimum to obfuscate your xap to at least a somewhat comfortable level. However I did find that while this worked in my Hello World demo, it didn’t work on one of my real world apps. I had to do some extra tweaking with that. Below are the screens that I used on one app that worked. I’m not sure what it was about the app that the approach above didn’t work with (maybe the extra assembly?) but it works and I’m happy with it. YMMV. Remember to test your obfuscated app on your device first before submitting to ensure you haven’t obfuscated the obfuscator.

    settings tab:

    image

    rename tab:

    image

    string encryption tab:

    image

    premark tab:

    image

    A few final notes

    • Play with the settings and keep bumping up the bar to try to get as much obfuscation as you can. The more the better but remember you can overdo it.
    • Always (always, always, always) deploy your obfuscated xap to your device and test it before submitting to the marketplace. I didn’t and got rejected because I had gone overboard with the obfuscation so the app wouldn’t launch at all.
    • Not everything is going to be obfuscated. Specifically I don’t see a way to obfuscate auto properties and a few other language features. Again, if you crank the settings up you might hide these but I haven’t spent a lot of time optimizing the process.
    • Some people might say to obfuscate your xaml using string encryption but again, test, test, test. Xaml is picky so too much obfuscation (or any) might disable your app or produce odd rendering effets.
    • Remember, obfuscation is not 100% secure! Don’t rely on it as a sole way of protecting your assets.

    Other Tools

    Dotfuscator is one just product and isn’t the end-all be-all to obfuscation so check out others below. For example, Crypto can make it so Reflector doesn’t even recognize the app as a .NET one and won’t open it. Others can encrypt resources and Xaml markup files. Here are some other obfuscators that support the Windows Phone 7 platform. Feel free to give them a try and let people know your experience with them!