Wednesday, 31 July 2013

Navigating code which uses IoC

Recently I've been navigating around lots of code which uses interfaces to implement Inversion of Control.  The problem is that every time you use F12 to 'Go To Definition' you are taken to the interface, not any of the available implementations.  Most of the time there is only one real implementation, the other(s) are for unit tests.
 
Here are your quick navigation options:

 

Put interface and implementation in the same file

A low-tech option is just to put the main implementation of the interface in the same file as the interface itself.  In reality this is often not an option.

 

Call Hierarchy

You can use the built in 'Call Hierarchy' (Ctrl+k, Ctrl-t) to show implementations of the given function.
 

 

Productivity Power Tools

Productivity Power Tools (see here) allow you to click on the interface name and see 'Implemented By'.  You can then open the list of functions to get to the function you need.

 

Code Rush

There's a plugin for CodeRush here but I couldn't get it to work (even after I remembered to Unblock the downloaded DLL).  Also I found that CodeRush made my IDE grind to a halt (the solution is VERY large)

 

Visual Assist X

Visual Assist doesn't help (but also doesn't hinder any of the other options)

 

ReSharper

Apparently if you have ReSharper then ALT+END will find all implementors.
 
Note these hints are a summary of this post.
Visual Studio user voice suggestion that the functionality is added (here)

Wednesday, 24 April 2013

How to assess user experience

Thu 7th March Tobias Komischke
Aims:
  • Suitability for task (e.g. Amazon = 15 tabs to get to the input box!)
  • Self-descriptive
  • Controllability
  • Conform to user expectations
  • Error tolerance
  • Suitability for individualisation
  • Suitability for learning
Example of proving UI was improved using a radar chart:

Avoid:
  • Non-standard UI controls
  • Inconsistency
  • No perceived affordance
  • No feedback
  • Bad error messages
  • No default values and bad cursor focus
  • Dumping users right in (completely empty OR really full)
  • No workflow support
Other UI considerations
 
Screen clutterAesthetics / human factors - clutter limits the brains ability to process info
Text legibilityCharacter sizes - well known optimum + minimum text sizes for handhelds / monitors / projection walls.
Hard to do for different form factors
Text orientationDon't use Marquee
Rotated right slightly better than left.
Horizontal is best
Colour contrastTools available on the web
Colour blind = 8% of men, 0.43% of women.  Mostly red/green
RAGs: Use both colour / shape and icon
Text alignment in menusLeft align is best (for English)
In forms: align text next to the control (proved using eye tracking)
top align is also ok (benefit is language translation when the text size will vary)
Bad = bottom right or in the input box (info has gone once input + watermarked text is hard to read + presume it's already been input)
Visual structure and flowGrid structure and flow
Improve readability, quicker learning
Standardisation reduces design
Add grid lines to measure conformance
OrientationWhere am IWhere have I come from
What's next
Icon qualityConcreteness = resemblance to real world counterpart
Complexity = Richness of details depicted (want low)
Semantic Distance (want low)
Data visualisationBar charts are best
Volume control worst (humans can't spot area changes)
Visual attentionWhere do people look?
Eye tracking is costly
OR Saliency modelling - use website "Feng GUI" to simulate where people will look first.  1 free heat map per day.
Usability testingReal users
Real tasks
Prototypes + real products
Thinking aloud
Qualitative + quantative data
7/8 people will find 80% of usability problems.  Diminishing returns.
Trend towards remote UI testing - easier + better tooling these days

Design for testing

Thu 7th March Kevin Jones
Our goal is to produce flexible, maintainable, defect free code.
 
Code:
  • Automate the build and deploy process
  • Don't leak UI in to domain layers
  • Don't leak DB access across layers
  • Define new types for each concept even if they are small
    • e.g. Money type rather than using a double.
  • Build facades
    • Amalgamate behaviour in to a new type
    • Hide complexity of underlying objects
  • Single responsibility principle
  • Using concrete types is often a bad idea
    • Code to interfaces
    • Can replace real objects with test objects
    • Can use Dependency Injection
    • Use of 'new' means we are tied to an implementation
Test:
  • Tests should be isolated
  • Unit tests shouldn't use system (file / DB etc.)
  • Test names should be descriptive (use the BDD style)
    • Given_When_Than()
    • e.g. GivenAUserService_WhenIAskForAllUsers_ThenAllUsersAreReturned()
  • Arrange -> Act -> Assert
Dependency Injection
  • Parameter injection
  • Setter injection
  • Constructor injection
  • Use an IoC container (e.g. Unity / Castle / Ninject / AutoFac for MVC)
  • IoC (Inversion of Control) is a principal, Dependency Injection is a consequence of IoC

Tuesday, 2 April 2013

Living happily with the GC

Wed 6th March Richard Blewett

This lecture was one of the more practical ones and mainly focused on using PerfMon to show how the GC works when various bits of code are run.  I'm not going to give a description of how the GC works, instead I'll concentrate on coding changes we can/should be making.

The main goal is to collect as much memory in Generation 0 as possible since Generations 1/2 are around 10 and 100 times slower respectively.

It's worth noting that as of .net 4 you can choose Asynchronous garbage collections for Generation 2.

There is a stage in garbage collection called Finalization which happens in case Dispose wasn't called on an object.  This is run using the Finalizer thread which is slow and its timing is unpredictable.  Simply by adding a destructor to a C# object the number of objects allocated per second drops by about a factor of 15.  If you need to remove references to unmanaged objects (e.g. icon/filestream/sqlconnections) consider using SafeHandle instead.

This example looks strange but helps if a GC happens half way through the Load function:
    
    void LoadData(string s)
    {
        this.data = null;
        this.data = XDocument.Load(s);
    }

Actions:

  • Run load tests with PerfMon garbage collections switched on.
  • Look at our use of destructors
  • Consider using SafeHandle instead of IDisposable
  • Profile to see what the current state of play is w.r.t memory usage / GC time.

Tuesday, 19 March 2013

DevWeek 2013: Overview


You can use this post either as an index of upcoming posts or an incredibly brief summary of the things I found interesting over the week.

For my colleagues, my full notes are in TFS in: "M:\TFS\C++\MooD\Docs\Misc\DevWeek 2013"

There's also a memory stick with all the slides on if anyone is really interested.

Monday

SharePoint 2013

  • Code runs under full trust.
  • 50% faster than predecessor (with 24Gb of RAM)
  • Farm / App / Sandbox solutions.  Should try and use Apps
  • Powershell is worth learning and useful for SharePoint development

Tuesday

Welcome to DevWeek

  • A question of craftsmanship (funny lecture + some links to interesting material)
  • Advances in the cloud computing platform (an advert for Azure)

Design patterns in the real world

  • Various patterns demonstrated using "Game of Life" example
  • Each class can contribute to many design patterns, not just one.

From the user to the unit test - how to start using tests

  • A description of SCRUM
  • Using Gherkin to specify scenarios
  • Arrange -> Act -> Assert
  • Selenium to test web

Light-weight architectures for everyone with the ASPNET WebAPI

  • WebAPI allows HTTP protocols without needing IIS / ASP.NET

Wednesday

Modern JavaScript

  • Encapsulation via Closures
  • Self invoking functions
  • Module pattern / revealing module pattern.
  • Confirmed that Sam's later work was using the right pattern.

Living happily with the GC

  • Using PerfMon to keep track of Gen0/1/2 collections
  • How to reduce frequency of slow collections
  • Why destructors are evil in C#

Evolution of the Entity Framework

  • Can auto migrate databases up/down versions
  • Code first POCO style development (plain old C# object)

Writing code that others can read.  A survival guide (for others)

  • Use Resharper
  • Commenting / consistency / clarity
  • Single responsibility principal
  • Function bigger than a screen is an alert to refactor

Thursday

Design for testing

  • Red, green refactoring
  • Use IoC / Dependency Injection
  • Confirmation that we're kind of doing it right (in some bits of the code base!)

How to asses user experience

  • Checklists of things to look for
  • "Feng GUI" is a good website which simulates eye tracking
  • Overlay a grid on your dialog to see how messy it is.

Emergent Design

  • Justifications for using TDD
  • Do things at the "Last Responsive Moment"
  • Try not to over engineer.  Rather respond to change as it happens.

Applied NoSQL in .net

  • MongoDB allows JSON objects stored against a primary key
  • Means that less JOINs happen
  • Very fast, depending on your data requirements.

Thursday, 14 March 2013

Code snippets in Blogger

Use the following link
http://www.manoli.net/csharpformat/format.aspx
And add custom CSS to your site (as the link advises)

A class which implements 'for each' in unmanaged C++

This is a way to make just about any class implement a C++ 'for each'.  In this example the existing way of iterating round a list is as follows:

CTypedPtrList<CPtrList,int*> myList;
POSITION pos = myList.GetHeadPosition();
while(pos)
{
    int* p = myList.GetNext(pos);
}

You need to implement a begin() and end() function which return an iterator class.
The iterator class must implement:
    void operator++();
    T operator*() const;
    bool operator!=(const iterator& other)

Once you have done this then the compiler will automatically allow you to write your iterator like this:
for each(int* p in myList)
{
}

Note that if your variable is const you may need to implement a version of everything which is const.

See below for a full implementation example built on CTypedPtrList:

template <class T> class PList : public CTypedPtrList<CPtrList> 
{
public:

    // Support for iterators.
    class iterator
    {
    public:
        iterator( PList<T>* p, POSITION pos ) 
            : m_pList(p), m_pos(pos), m_pointer(NULL) 
        {
            if( m_pList )
            {
                m_pos = m_pList->GetHeadPosition();
                if( m_pos )
                    m_pointer = m_pList->GetNext(m_pos);
            }
        }

        void operator++(int) 
        {
            if( m_pos==NULL ) m_pointer = NULL;
            else    m_pointer = m_pList->GetNext(m_pos);
        };

        void operator++()
        {
            this->operator++(0);
        };

        T* operator*() const { return m_pointer; }

        bool operator!=(const iterator& other) const 
        {
            return m_pointer!=other.m_pointer;
        }
    protected:
        PList<T>* m_pList;
        POSITION  m_pos;
        T*        m_pointer;
    };
    //
    iterator begin() { return iterator(this, GetHeadPosition()); }
    iterator end()   { return iterator(NULL,NULL); }
};