Commenting Strategies in C# and ASP.NET Web API

asp.netccommentsrestweb-api

I've been working on a ASP.NET Web Api 2 project as a learning exercise, and I was wondering what the norm regarding commenting is.

I use the Repository / Service Pattern, and everything is very much decoupled, which results in having a large number of classes whose purpose is pretty clear. I also name my variables in a way that they explain themselves.

This leaves me wondering what I should actually be commenting in this scenario.

  • Should I just stick to class-summaries ( even if the class itself is self-explanatory ) ?
  • What about self-explanatory methods ?
  • Do data / business entity classes need a summary ?
  • What about interfaces ?

To give a bit more context, here is one of my repository classes which provides CRUD functionality:

public class UserRepository : RepositoryBase<User, decimal>
{
    private readonly ShortStuffContext _context;

    public UserRepository(ShortStuffContext context)
    {
        _context = context;
    }

    public override IEnumerable<User> GetAll()
    {
        return _context.Users.BuildUser();
    }

    public override User GetById(decimal id)
    {
        return _context.Users.FirstOrDefault(u => u.Id == id).BuildUser();
    }

    public override CreateStatus<decimal> Create(User entity)
    {
        if (_context.Users.Any(u => u.Id == entity.Id))
        {
            return new CreateStatus<decimal> { status = CreateStatusEnum.Conflict };
        }

        var user = new Data.Entities.User();
        user.InjectFrom<SmartConventionInjection>(entity);
        _context.Users.Add(user);
        _context.SaveChanges();

        return new CreateStatus<decimal> { status = CreateStatusEnum.Created, Id = user.Id };
    }

    public override UpdateStatus Update(User entity)
    {
        var dbUser = _context.Users.FirstOrDefault(u => u.Id == entity.Id)
                             .InjectFrom<NotNullInjection>(entity);

        if (dbUser != null)
        {
            var changeTrackerUser = _context.ChangeTracker.Entries<Data.Entities.User>()
                            .FirstOrDefault(u => u.Entity.Id == entity.Id);

            changeTrackerUser.CurrentValues.SetValues(dbUser);
            if (_context.SaveChanges() == 0)
            {
                return UpdateStatus.NoChange;
            }
            return UpdateStatus.Updated;
        }
        return UpdateStatus.NotFound;
    }

    public override void Delete(decimal id)
    {
        var user = _context.Users.FirstOrDefault(u => u.Id == id);
        _context.Users.Remove(user);
        _context.SaveChanges();
    }
}

So in a class like that, is it worthwhile to put a summary like "Provides CRUD functionality for the User Data Entity" ( and then repeat that summary for every other repository ), or not ? What about method comments, or inline comments?

Edit: My project is on Github. I know about adding comments to more complex methods, and I'm planning on adding comments to the Extensions and the ValueInjecter classes soon ( which hold by far the most complex code ). Apart from that, any advice regarding where to put comments is very much welcome.

Best Answer

There is no definitive answer: some people will be inclined to add comments to every class and method; others will try to avoid commenting things which are already explicit enough.

  • If you follow StyleCop default rules, you have to comment every member, including private fields. You might want to suppress the warnings if the code is really repetitive. But if it is, you may ask yourself why is it not automatically generated (note: automatically generated code is marked specifically, and is not processed by StyleCop).

  • If you don't, feel free to comment as much or little as you feel appropriate. If I were maintaining the piece of code from your question, I would have added comments on every method, just to simplify my work later: I'd rather read a sentence in a tooltip in Visual Studio rather than try to guess right the meaning of the method. On the other hand, I would avoid commenting something like Title property of the class Product.

In all cases, try to bring something useful on those comments, not just repeat the name of the method or property. For example, if the class Product has a property Description, one way is to write:

/// <summary>
/// Gets the description of the product.
/// </summary>

This comment doesn't bring anything useful. Another possibility is this one:

/// <summary>
/// Gets the piece of text which is displayed publicly and is usually written by the
/// managers. The description is localized for the current user.
/// </summary>

Here, you bring three pieces of useful information:

  • The description is public. The web app may also have an internal summary field where managers can write text for themselves.

  • The description is usually written by managers. This helps understanding the business logic.

  • The description is a string translated in the language of the current user (probably CultureInfo.CurrentCulture).