August 1018

If I ran DevDiv… my take on things

There have been some very thought provoking blog posts focussing on .NET recently and this post is my reaction to them. In “How I Feel About The .NET World Lately” Davy Brion rants a bit about some stuff he doesn’t like and Ayende has some ideas for how he would change things going forward.

Davy’s post is, by his own admission, a rant. He refers to the Microsoft recommended development practices and products as “Fisher Price Development”, a sentiment I share to some degree. In my opinion a developer is someone who can write code and not someone who can only use the wizards in Visual Studio. Microsoft has plenty of documentation on how to use their tools and write code as long as you want to do it the Microsoft way, but it isn’t much help if you’re trying to do things in the real world. Now I don’t think it’s Microsoft’s place to try to teach people how to be a good developer, but I would like to see better quality documentation. We know they can write good code so why settle for poor quality on MSDN, proper use should be made of using statements and care taken to ensure that objects are properly disposed – even in these simple examples. Hello world samples are useful when you’re trying to learn something new and sometimes so obscure that it’s hard to see how to apply their example to what you’re trying to find an answer to. To quote my friend Karl:

When I was trying to learn how to use delegate functions, the MSDN example was something to do with an array of dinosaurs which were sorted using a delegate function. It was so utterly unrealistic it was no use and didn't teach me anything about delegates!

There are times when I need to ‘hack’ something, occasionally it makes sense to just throw in some raw ADO.NET code to pull back a simple value from a database and setting up an ORM for just that one bit of data is over kill. Like sorting your record collection alphabetically even though you only have one album. That said I still think there’s room to have an advanced / real world examples that show production quality code; including defensive programming, error logging and proper validation – people need to know what proper code looks like and this would be a good opportunity for Microsoft to lead people to a professional programming style. They could turn their developers loose on MSDN once a week and let them add in the advanced concepts, I’m not asking for much – just one afternoon a week. Granted this might not give documentation to suit all tastes but most developers can adapt code samples to something that works for them, so those in the alt.net community could use it as a jumping off point and maybe somewhere like codebetter.com could start it’s own MSDN style resource?

Where are things going?

A lot of attention seems to be focused (at the moment) on the entry level .NET developers – my concern here is that this appears to be at the expense of those at the other end of the spectrum. Both WebMatrix and LightSwitch (it should be noted that I haven’t actually used either of these, so you’ll have to take my opinions with a pinch of salt) are designed to allow people to:

solve specific business needs by enabling them to create professional-quality business applications, regardless of your development skills

The trouble I have with this strategy is that it hides the complexity of creating professional software from those using the tools so when you need to do something that isn’t possible through the wizards you’re in real trouble. I have seen quite a few people call themselves developers, even get jobs as developers, who can’t actually code and I worry that tools such as these will only encourage more people. Please don’t misinterpret me here, I am not saying there’s anything wrong with having a cool IDE that lets anyone put together a nice program – everyone has to start somewhere right, but that’s not the same as becoming a developer yet that’s the impression that’s being given and doing that devalues professionals and the years of effort they’ve put in to learn their craft. I have a Sony A200 and I can take pretty decent photos with it, but I am not a professional photographer, nor do I delusions that I am one.

Ideally I’d like these newer tools to provide a nice easy path into the more serious end of programming but I fear that mastery over something like WebMatrix isn’t really going to help someone migrate to using Visual Studio.

What can we do about it?

So that’s a rough summary of where things are at the moment, and a glimpse of where it looks like they’re heading, so what can / should be done about it?

Good question, in fact that’s pretty much the question Ayende tries to answer,

if you were in Scott [Guthrie]'s shoes, what would you do?

  • I’m very much behind Ayende’s call to kill duplicated effort, his example of the embarrassment caused by LINQ to SQL & Entity Framework fiasco illustrates this point nicely, they should have identified the overlap while they were still internal projects and unified them before they saw the light of day. This is how I feel about their tools, internally they need to collaborate / communicate more to know what other teams are doing. I know a developer who refuses to look at new technologies because they get killed off and he ‘wasted his time learning UML and other stuff’ – essentially he’s afraid to invest his time into learning something new in case it gets pulled within a year or two, and to be honest you can’t really blame him if his fingers have been burned before.
  • This point was made by Karl and I’m simply repeating it here: “Stop trying to out-X X!  Microsoft software does its own stuff and does some brilliant things.  But you can't out-Google Google, out-Linux Linux or out-Apple Apple.  That's why the Phone 7 stuff is so interesting to watch develop because, unlike Android, they've actually done something new rather than just copy the current state of the art.”
  • I’ve said I feel there is a lot of attention focussed on the entry level developers – well I also agree with Ayende that Microsoft should focus some love towards the non entry level developers, this shouldn’t be allowed to continue.

Now in a cheesy attempt to generate some comments… what would you do dear reader?

Spread/Promote this post

If you enjoyed this article, consider bookmarking or helping me promote it! Thanks.

  • Del.icio.us
  • Digg It!
  • Technorati
  • BlinkList
  • DZone It!
  • Furl
  • NewsVine
  • Reddit
  • StumbleUpon

Don't miss another post

Subscribe to SJM Dev's RSS Feed to stay updated with our latest articles!

Permalink | Comments (1)

July 1031

SaveOrUpdate with Entity Framework, mostly update though!

As I take my first steps with Entity Framework CTP 4 (Magic Unicorn) I realise that all isn’t quite as sweet and smooth sailing as the examples would have me believe.

What does that mean? Well for a while I’ve taken the approach that methods that make changes to the database return a Boolean which makes it easy to give simple feedback to the user, and I've combined my Save and Updates because the only difference between them is that in the case of an update the ID is known, if the ID is not known then it is a new item and it must be a save (that I've handled in the stored procedures). In the case of my DAL I'll have a method such as this:

public static Boolean Save(ToDo toDo)
{
    SqlParameter[] parameters = {
        new SqlParameter("@ToDoID", SqlDbType.Int, 4)
        , new SqlParameter("@StaffID", SqlDbType.TinyInt, 2)
        , new SqlParameter("@TaskName", SqlDbType.VarChar, 100)
        , new SqlParameter("@DueDate", SqlDbType.SmallDateTime)
        , new SqlParameter("@PriorityID", SqlDbType.TinyInt, 2)
        , new SqlParameter("@Notes", SqlDbType.VarChar, 6000)};
    parameters[0].Value = todoID == null ? parameters[0].Value = DBNull.Value : parameters[0].Value = todo.ID;
    parameters[1].Value = todo.Staff.ID;
    parameters[2].Value = todo.TaskName;
    parameters[3].Value = todo.DueDate == null ? parameters[3].Value = DBNull.Value : parameters[3].Value = todo.DueDate;
    parameters[4].Value = todo.Priority.ID;
    parameters[5].Value = todo.Notes;
    try
    {
        SqlHelper.ConnectionString(DbConnection);
        SqlHelper.ExecuteNonQuery("uspSav_ToDo", parameters, out _rowsAffected);
        return (_rowsAffected >= 1);
    }
    catch (Exception ex)
    {
        _log.Error(ex.ToString());
        return false;
    }
}

So from there I can just call my Save method and provide user feedback based on what it returns.

if (controller.Save(MyObject))
{
    MessageBox.Show("the save worked");
    // Other stuff…
}
else
{
    MessageBox.Show("the save failed");
    // Other other stuff…
}

However the examples given, for EF at least, seem to always treat the Save (create) and Update methods separately even though the examples given are pretty simple cases. The trouble is that I then have 2 nearly identical methods differing only in 1 parameter and I would prefer otherwise (I realise this may violate the Single Responsibility Principle but actually I’m not sure it does and I’m prepared to make that sacrifice for the maintainability of my code).

Initially I found I was going down that path though, 1 (public) Save method and 1 (public) Update method and what I found really worrying was that I needed to do a bunch of left right assignment stuff in my update method.

public void SaveToDo(ToDo todo)
{            
    context.ToDo.Add(todo);
    context.SaveChanges();
}

public void UpdateToDo(ToDo updated)
{
    var todo = context.ToDo.Find(updated.ID);
    todo.DateCompleted = updated.DateCompleted;
    todo.DateDeleted = updated.DateDeleted;
    todo.DueDate = updated.DueDate;
    todo.Notes = updated.Notes;
    todo.Priority = updated.Priority;
    todo.Staff = updated.Staff;
    todo.TaskName = updated.TaskName;
    todo.Version ++;
    context.SaveChanges();
}

Yuk! I really didn’t like this, but I’d spent a little while Googling and hadn’t come across anything that really explained how you updated an entity using Entity Framework, even the sample Scott Gu gives in his code first development with EF4 post shows manually updating a property (but fails to address updating many properties). Then I had a lucky break in discovering the Attach method (as yet I haven tested this to see that it works but) I think it does what I want and means I don’t have to do all that tedious left-right property assignment you see in UpdateToDo above. What I’ve ended up with is this:

public void SaveOrUpdate(ToDo todo)
{
    if (todo.ID != -1)
        Update(todo);
    else
    {
        context.ToDo.Add(todo);
        context.SaveChanges();
    }
}

private void Update(ToDo updated)
{
    updated.Version++;
    context.ToDo.Attach(updated);
    context.SaveChanges();
}

Publically I’ve just got the single SaveOrUpdate method (I have to confess I 'borrowed’ this name from NHibernate) so now anything that’s saving something, whether it’s new and a save or existing and therefore an update all calls the same method SaveOrUpdate and if the ID is not –1 then it must be an existing record so it calls the private Update method. The Update method increments the Version property (again I’m borrowing from NH a little), then attaches the object so when I call SaveChanges my updated object is persisted for me.

If anyone has any observations on this approach I would like to hear them – it’s early days for me here so I may be re-inventing the wheel or worrying about something there’s no need for or I may even have a nice pattern, who knows… but here’s hoping Scott Hanselman picks up this post, reads it and decides to do one of his Weekly Source Code reviews on it Winking smile

Spread/Promote this post

If you enjoyed this article, consider bookmarking or helping me promote it! Thanks.

  • Del.icio.us
  • Digg It!
  • Technorati
  • BlinkList
  • DZone It!
  • Furl
  • NewsVine
  • Reddit
  • StumbleUpon

Don't miss another post

Subscribe to SJM Dev's RSS Feed to stay updated with our latest articles!

Permalink | Comments (0)

July 1027

log4net Gotcha with .Net 4.0 Applications

I’ve been using log4net in an application for a little while, it took some time to get it set up (maybe I’ll do a post about that in the future?) – but once it was set up I could call it from any form in my project and log whatever I wanted. For this particular project I decided I was going to create a new project and bring in my existing code, upgrade it to .Net 4.0 and fix any build errors. What confused me was that log4net wasn’t recognised in my project.

I checked my references and sure enough log4net showed up in there, my app.config file hadn’t changed but as soon as I tried a Using statement there were problems, trying to compile resulted in the following error: “The type or namespace ‘log4net’ could not be found (are you missing a using directive or an assembly reference?)”. Well quite clearly I wasn’t missing the using statement and I could see log4net in the references.

Well there are 2 versions of .Net 4.0, the Client profile and the full profile; the client profile only has some of the framework, it’s trying to reduce the footprint of the framework – however it doesn’t have system.web.dll and it seems that log4net requires that in order to work. So the solution was to change the Target Framework from “.NET Framework 4 Client Profile” to “.NET Framework 4”, allow Visual Studio to update the project (it will want to close it, which is fine), when it reopens the project log4net will not throw the error and I can get on with converting my project.

Spread/Promote this post

If you enjoyed this article, consider bookmarking or helping me promote it! Thanks.

  • Del.icio.us
  • Digg It!
  • Technorati
  • BlinkList
  • DZone It!
  • Furl
  • NewsVine
  • Reddit
  • StumbleUpon

Don't miss another post

Subscribe to SJM Dev's RSS Feed to stay updated with our latest articles!

Permalink | Comments (1)

July 1024

Entity Framework 4 - my first steps

I’m working on a pet project that I’ve wanted to migrate to using an ORM for a while. Tonight I took the plunge and decided I’d see how easy Entity Framework 4 (EF) makes things.

The Code-First Development with Entity Framework 4 post from Scott Gu made it look pretty easy and I figured I could probably swap out all my existing data access layer quite quickly, after all it’s promising to do most of the dirty data plumbing for me. Sure enough it’s really quick and easy to create a bunch of POCO classes but I’ve already hit 2 gotchas that I thought I’d share:

  1. Nullable datatypes for primary keys are not allowed. Typically I’ll create public int? ID{get; set;}, if the ID isn’t known then this is a new entity, if it is known then I've retrieved the object from the database and so this will be an update. However nullable datatypes are not accepted, so I’ll have to modify the way I’ve been doing these things.
  2. Object inheritance. I have a Contact class that defines some basic properties contacts have, then 2 derived classes (Customers and Suppliers). As all contacts should have an address I want to add an Address property to Contact but I’m getting an error.

    The navigation property 'Address.Contact' references an entity type 'Data.Models.Contact' that is not contained within an entity set. Reference a specific object set type 'Data.Models.Supplier,Data.Models.Customer' instead.

    So instead of having 1 place to deal with the Contacts Addresses relationship (and in this case it is only very simple, contacts are allowed 1 address only), I now need 2 places?

The code

This is what I've got for the Contact class

using System;

namespace Data.Models
{
    public abstract class Contact : BaseEntity
    {
        public virtual Address Address { get; set; }
        public DateTime DateAdded { get; set; }
        public String Email { get; set; }
        public String FirstName { get; set; }
        public String LastName { get; set; }
        public String Title { get; set; }
    }
}

and this is for the Address class:

using System;

namespace Data.Models
{
    public class Address : BaseEntity
    {
        public virtual Contact Contact { get; set; }
        public String County { get; set; }
        public DateTime DateAdded { get; set; }
        public String Phone { get; set; }
        public String Postcode { get; set; }
        public String Street { get; set; }
        public String Town { get; set; }
    }
}

finally this is the Supplier class:

using System;
using System.Collections.Generic;

namespace Data.Models
{
    public class Supplier : Contact
    {
        public virtual ICollection<Component> ComponentsSupplied { get; set; }
        public virtual ICollection<Product> ProductsSupplied { get; set; }
        public String SupplierName { get; set; }
    }
}

So nothing overly complex going on here – Suppliers implement Contact and provide a SupplierName property. I’m not sure I get why EF won’t let me define my classes this way.

That said this will make me significantly more productive once I get over this initial learning curve. I’ve been wanting to implement NHibernate in this project for a little while but messing about with xml files compared to the quick approach with EF means that I’ll probably use EF for all simple things for the moment – well until I get something I can experiment with using NH Open-mouthed smile

Spread/Promote this post

If you enjoyed this article, consider bookmarking or helping me promote it! Thanks.

  • Del.icio.us
  • Digg It!
  • Technorati
  • BlinkList
  • DZone It!
  • Furl
  • NewsVine
  • Reddit
  • StumbleUpon

Don't miss another post

Subscribe to SJM Dev's RSS Feed to stay updated with our latest articles!

Permalink | Comments (1)

July 1020

CodeRush Rename with F2 key

Rory Becker mentioned in a recent post CodeRush 101 (by Mehul Harry) that he uses F2 to invoke the Rename Refactoring. That was a forehead slapping moment for me… of course it makes perfect sense F2 should activate the Rename refactoring. I had a look in the Options and it does appear to be there, however it wasn’t active. Fortunately I found the answer on the DevExpress forums, I’ll quote it here, I’m sure no one will mind:

By default the Alternative Bindings are Disabled, select the Alternative Bindings "folder" and Enable it, then all the shortcuts that are in the Alternative Bindings should come to life ;)

Spread/Promote this post

If you enjoyed this article, consider bookmarking or helping me promote it! Thanks.

  • Del.icio.us
  • Digg It!
  • Technorati
  • BlinkList
  • DZone It!
  • Furl
  • NewsVine
  • Reddit
  • StumbleUpon

Don't miss another post

Subscribe to SJM Dev's RSS Feed to stay updated with our latest articles!

Permalink | Comments (0)