The Edge

Web application development insights written for our team, but open to the development community.

Automatic Properties in vb.net

September 7, 2010

With VB10 in Visual Studio 2010 came a swag of improvements that make code both easier to write and easier to read.

One of those improvements has been with c# for a while; automatic properties.  In c# you can declare a property like so;

     public string Name { get; set; }

This will create the property called “Name”, and when compiled will create the private, member variable _Name.

In most cases where a property is declared, we never need to access the member variable associated with the property.  This is particularly true of our domain entities where properties are often used to simply store data.

Now to vb.net.  Up until Visual Studio 2010, a property needed to be declared and used in a way similar to this (being overridable due to our use of nHibernate);

    Public Overridable Property FirstName() As String
        Get
            Return m_FirstName
        End Get
        Set(ByVal value As String)
            m_FirstName = value
        End Set
    End Property
    Private m_FirstName As String

This whole chunk of code can now be narrowed down to;

    Public Overridable Property FirstName() As String

That makes a big difference when putting together a large domain model or reading through a domain entity code – to see all the properties in a short, concise list.

To initialise the property with a default value (you would have typically assigned this to the member variable), you can just assign it to the property;

    Public Overridable Property Lines() As IList(Of Line) = New List(Of Line)

Or, you can use the DefaultValue attribute;

    <defaultvalue ("New Customer")> 
    Property Name() As String Implements ICustomer.Name

 

References

MSDN: Auto-Implemented Properties (Visual Basic)

No Comments on Automatic Properties in vb.net

Domain Driven Design

September 3, 2010

Domain-Driven Design describes a software development pattern that focuses on encapsulating the customer’s business processes and relationships (i.e. customers, orders, inventory) directly within our software. This is called the "domain" or “model”.

This ensures both a highly customised approach, and that the software will closely align with its intended purposes.

Usually one of the first steps a consultant will take when planning software will be to design a "domain model", which should be clearly understandable by the customer and ensures that we have carefully considered the customer’s requirements.

What is DDD?

What is Domain-Driven Design?

Over the last decade or two, a philosophy has developed as an undercurrent in the object community. The premise of domain-driven design is two-fold:

  • For most software projects, the primary focus should be on the domain and domain logic; and
  • Complex domain designs should be based on a model.

Domain-driven design is not a technology or a methodology. It is a way of thinking and a set of priorities, aimed at accelerating software projects that have to deal with complicated domains.

To accomplish that goal, teams need an extensive set of design practices, techniques and principles. Refining and applying these techniques will be the subject of discussion for this site, generally starting from the language of patterns laid out in Domain-Driven Design, by Eric Evans.

http://domaindrivendesign.org/resources/what_is_ddd

From a Development Perspective

What this means in code, is that we generally first design the classes that belong to the domain model, and the database schema (if required) is then generated from that, either automatically or manually.  This is opposite to the common practice of designing a database schema, and then building either queries or data-classes in the code around the database.

Usually the code is completely abstracted from the database itself, allowing us to focus on the purpose of the code (to fulfil a business requirement) rather than the structure of the data.

Resources

Domain Driven Design Quickly

domaindrivendesign.org

No Comments on Domain Driven Design

Showing files in MVC.net

September 1, 2010

This is one of the easiest things to do with MVC, yet, it is often done in ways that make it look complicated.

It is as simple as using the “File” controller helper method to create and return a FileResult (you do this instead of returning a View) by passing the file name and content type;


    Function ShowFile(ByVal fileName as String) As ActionResult
	
        Return File(Server.MapPath("files/" & fileName), System.Net.Mime.MediaTypeNames.Application.Pdf)

    End Function
	

At i-Possible, we tend to encapsulate any dynamic documents in an entity that is saved to disk (or perhaps the cloud) by the repository, and so we can use the data stored in this entity instead (not especially that there is no need to store it to a temporary file location);


    Function Display(ByVal fileId As Guid) As ActionResult

        Dim document As Core.File = DomainController.Files.Repository.GetByID(fileId)

        If document IsNot Nothing Then

            Return File(document.Content, document.MIMEType)

        End If

        'Using the up and coming MVC3 we could return a 404 here instead
        Return Nothing

    End Function

If you want the document do download instead of display in the current window, you can set the content disposition automatically by supplying a file name;


    Function Display(ByVal fileId As Guid) As ActionResult

        Dim document As Core.File = DomainController.Files.Repository.GetByID(fileId)

        If document IsNot Nothing Then

             Return File(document.Content, document.MIMEType, document.FileName)

        End If

        'Using the up and coming MVC3 we could return a 404 here instead
        Return Nothing

    End Function

No Comments on Showing files in MVC.net

Dealing with Issues

August 26, 2010

While we must strive always to create code that is free of bugs, with the custom software we create bugs are inevitable.  This should never lead to complacency – we should be diligent in both testing code and correcting bugs quickly.

Each member of our team is responsible for correcting bugs in any code that they have created.  This is important for our processes to work correctly, and it is also one of the factors that defines a contractor in Australian employment law.

As bugs are discovered, they will generally be added to an issues list, and then assigned to the responsible contractor as part of a Work Week (meaning they will also be assigned to you in Basecamp)

You will see them appear in your Work Week email, without a value assigned, like so;

image

Once they have been added to your Work Week, they are considered part of that Work Week and the Work Week will not be considered complete until the issue is corrected.

On some larger projects, issues will be assigned a priority which defines how quickly they need to be resolved.  This will effect which work week it is assigned to;

Level Description Resolution Time Work Week Assignment
Urgent Broken functionality affecting most users. ASAP (less than 24 hours). Will be added to the current work week if raised prior to 5pm Thursday, otherwise it will be manually assigned to you and then added to the following work week.
Priority Broken functionality affecting some users. Less than 48 hours. Will be added to the current work week if raised prior to 5pm Wednesday, otherwise it will be manually assigned to you and then added to the following work week.
Open New Issues, or Issues causing minor disruption. Within the work week it is added to. Will be added to the following work week, and assigned along with it.
Cosmetic Issues not affecting functionality Within the work week it is added to. Will be added to the following work week, and assigned along with it.

Note especially that urgent and priority issues are expected to be dealt with within the “Resolution Time” and not necessarily by the end of the Work Week.  Not having the issue corrected by the end of the Work Week will cause the work week to be considered incomplete, but if issues are not completed within the expected resolution time then they may be corrected on your behalf by another team member, and the cost of them doing this will be deducted from future payments to you.

The following points should also be considered regarding issue management;

  • Issues should be dealt with before new features.  If an issues arises, feature development should be put on hold to fix it.
  • If a project is live, then you must always develop new features in a feature branch of the source repository.  If there isn’t one, then ask the person managing your work work for it to be created.  i.e. You should never be working with the source “trunk” when that project is live.
  • Always correct issues against the code in the repository “trunk” and check them in as soon as possible. 
  • To aid in the above two points, you should always have ready a working copy of both the trunk and any feature branches you are currently working on.
  • Test, test, test!  You need not test the whole platform every time you make a change (UAT), but you are responsible to test the feature / issue that you are working on and any related code in a variety of scenarios to make sure that it actually works (Unit Testing).  Careless coding on the first run may result in less work being offered in the future.

Always remember: Code is Poetry

No Comments on Dealing with Issues

Naming Conventions: .net

August 21, 2010

Hungarian notation seems now to be a thing of the past, and when it is used, it seems that everything is either an oObject.  Worse, when you see it used incorrectly, such as calling some non-integer object iObject.

So, it’s time to set some new standards I say.

Drawing from sources listed below, here is a list of common name types used throughout vb.net and c# and how they should be formatted.  These seem to be in line with the conventions used within the .net platform itself.

Note that in all cases, abbreviations should be avoided (i.e. use mobileNumber instead of mobNo) and acronyms of thee or more letters should be pascal case (i.e. Html istead of HTML)

Local Variables & Parameters: Within a method or property, local variables names should describe the purpose, using camel case – beginning with a lowercase letter with the first letter of each word beginning with a capital. 

  • comment
  • posts
  • tagCount
  • ByVal categoryId
  • iLoop
  • oCategories
  • commentSave
  • Post1

Member Variables:  Variables localised to classes should be in camelcase, prefixed by an underscore (_);

  • _orderId
  • _items
  • _totalPrice
  • mDeliveryCharge
  • m_postalAddress

Properties & Public Member Variables: Use Pascal Case – beginning each word with a capital, including the first.

  • OrderId
  • Items
  • totalPrice
  • deliveryCharge
  • propPostalAddress

Methods (Functions & Subs):  Pascal case.  Begin with a verb where possible.

  • GetPosts
  • SaveCategories

Classes: Pascal case, using nouns where possible.  Do not begin the class name with an I unless followed by a lower case letter to avoid confusion with interfaces.

  • Order
  • Item
  • CreditCard
  • clsCustomer
  • Buying

Interfaces: As with classes, but beginning with a capital I.

 

Sources

Visual Basic Naming Conventions (MSDN)

.net Naming Conventions and Programming Standards – Best Practices

No Comments on Naming Conventions: .net

Simplifying creating a list in vb.net

August 20, 2010

Often we need to create a list of arbitrary items in vb.net.

A common scenario when working with MVC is creating SelectListItems for use in a drop down list.

We would often create code like the this;

        Dim deductions As New List(Of Mvc.SelectListItem)
        deductions.Add(New SelectListItem() With {.Text = "PAYG", .Value = "PAYG"})
        deductions.Add(New SelectListItem() With {.Text = "GST", .Value = "GST"})
        deductions.Add(New SelectListItem() With {.Text = "Superannuation", .Value = "Superannuation"})
        deductions.Add(New SelectListItem() With {.Text = "Savings", .Value = "Savings"})
        deductions.Add(New SelectListItem() With {.Text = "Child Support", .Value = "ChildSupport"})
        ViewData("deductionType") = deductions

This can be simplified by creating an array instead;

        ViewData("deductionType") = {
                New SelectListItem() With {.Text = "PAYG", .Value = "PAYG"},
                New SelectListItem() With {.Text = "GST", .Value = "GST"},
                New SelectListItem() With {.Text = "Superannuation", .Value = "Superannuation"},
                New SelectListItem() With {.Text = "Savings", .Value = "Savings"},
                New SelectListItem() With {.Text = "Child Support", .Value = "ChildSupport"}
        }

Note that in vb.net 10.0 we don’t need to add the _ at the end of lines that obviously continue on the next line, such as these.

An array will work for most scenarios, but if it is indeed a list we are after, then we can create a list by adding .ToList() to the end, like so;

        ViewData("deductionType") = {
                New SelectListItem() With {.Text = "PAYG", .Value = "PAYG"},
                New SelectListItem() With {.Text = "GST", .Value = "GST"},
                New SelectListItem() With {.Text = "Superannuation", .Value = "Superannuation"},
                New SelectListItem() With {.Text = "Savings", .Value = "Savings"},
                New SelectListItem() With {.Text = "Child Support", .Value = "ChildSupport"}
        }.ToList()

No Comments on Simplifying creating a list in vb.net