Showing all posts by crmckenzie
Review: HTML5 Conference in Austin, TX

I didn’t realize this when I signed up, but the DevCon5 Html5 Summit was a conference within a conference. The larger conference was an ITEXPO. The ITEXPO conference was focused more on infrastructure than development—in fact as far as I could tell, HTML5 was the only developer-centric conference at the entire event. This did not turn out to be a good thing for me. I noticed maybe 20 or 25 developers for the HTMl5 portion of the event.

The Negative

The sessions themselves had a few problems. First, the focus was almost all on mobile and app development. I realize that the world is changing and that more and more people are developing for the mobile platforms, but there are an awful lot of us that are building applications for the business we are trying to support. It would be nice if someone would discuss benefits to the business of the new HTML5 goodies. There was a little of that in the sessions, but it wasn’t very meaty. Yes, it’s great that you can make images float across the page, but my business users don’t really care about that.

The second problem, which perhaps isn’t the speaker’s fault, is that no one was really super-excited about HTML5. Since the focus was on apps for the mobile platforms, most speakers spent time acknowledging that the write-one-run-anywhere promise of HTML5 isn’t a reality, and likely wont’ be for a long time (but it’s getting better!).

Another issue with some of the speakers is that they did not seem to know very much about HTML5. If I had to reverse-engineer their talk, I would say that there was something they wanted to learn about, they learned just enough about it to fill up an hour of speaking, and then stopped. They were unable to answer questions about possible uses for the bits they were covering beyond their demo. Several speakers also did not have working demos.

The Positive

The best part of the sessions is that I got a lot of tools and references to other sessions that might fill out some of what’s missing. Here are some of the things that were referenced:

There were a very few principles and practices discussed. They are:

  • Get familiar with messaging in javascript.
  • If you’re going to support mobile, develop for mobile first—then the desktop.
  • 1 class per js file.
    • I especially like this one because it implies that you should still be writing classes in javascript.

Presenters I’d Like to See Again

Instead of picking on the presenters I thought were less than spectacular, I thought it would be better to shout the names of those who were particularly good. These are people that I’d enjoy talking to about web development again.

  • Jonathon Morgan – His talk on HTML5 vs. Native apps was well-reasoned and balanced. His enthusiasm for development was refreshing.
  • Tom Shafron – He is the current CEO of Viewbiquity. His session was on machine-to-machine communication in javascript. It was in his talk that we got into javascript best practices and patterns.
  • Jesse Cravens – His session on node.js was substantive and interesting. Most of the libraries mentioned above came from his presentation.
Simple.Validation 0.6.1 Released

What’s new?

Testability has been kind of an issue for us with code that relies on the static Validator class. To improve the situation, I added IValidationEngine as an alternative. Validator is still fully backwards compatible

  • Addition of the IValidationEngine interface
  • The DefaultValidationEngine requires an instance of IValidatorProvider for its constructor
  • Validator.SetValidatorProvider() has been marked obsolete. You can still use it, but it will have the side-effect of over-setting Validator.ValidationEngine to a new instance of DefaultValidationEngine.
  • Added a NinjectModule to Simple.Validation.Ninject that configures the DefaultValidationEngine and DefaultValidatorProvider automatically.
Install-VSCommandPrompt Powershell Script updated
API Design: Batch Operations

When designing a batch API, it is important that the return results be relatable to the individual arguments that were asked to be processed.

Consider an API that takes a list of objects to perform an operation on. It might have a method signature that looks like this:

        Response Process(Record[] records);

 

What is a good design for the Response object? I recently encountered a situation in which I was given a response object like this:

    public class Response
    {
        public bool Success { get; set; }
    }

 

Okay, actually it was more like this:

        bool ProcessTheRecords(int[] ids);

 

The problem with this approach is that when the operation fails there is nothing on the Response to indicate the nature of the failure. A better Response object might look like this:

    public class Response
    {
        public bool Success { get; set; }

        public OperationResult[] ErrorsAndWarnings { get; set; }

        public ProcessRecordResult[] Results { get; set; }
    }

    public class ProcessRecordResult
    {
        public string RecordIdentifier { get; set; }

        public OperationResult[] ErrorsAndWarnings { get; set; }
    }

    public class OperationResult
    {
        public string Message { get; set; }
        public Severity Severity { get; set; }
    }

    public enum Severity
    {
        Error = 1,
        Warning =2,
    }

Why is this better? Response.ErrorsAndWarnings lets me see if anything went wrong with the operation outside of any particular record. There should be a ProcessRecordResult for each record passed into the method call. Each ProcessRecordResult has its own list of ErrorsAndWarnings that indicates what may or may not be wrong with a specific record.

The purpose of the response object is to give enough information to the caller so that they can adjust their failed request into a successful one. Minimize the size and shape of the data required to perform the operation. Maximize the size and shape of the data required to understand what went wrong during the operation. These principles apply to non-batch operations as well, but they are especially frustrating when there’s an error in one of hundreds of records.

Simple.Validation 0.5.0 Released

New Feature

Message() method has been overloaded to accept a function to build the validation message while the object/property is being validated.

Example:

var validator = Properties<Employee>
    .For(e => e.FirstName)
    .Required()
    .Message((context, value) =>
        {
             customMessage = string.Format("Custom Message format '{0}'", value);
             return customMessage;
        });
Origin Story: How I Became a Software Developer

Scott Hanselman recently posted his story about how he became a software developer. This is mine.

I was in debt. And I needed money.

When I was in my early 20’s I didn’t have much going for me. I had quit high school in the 10th grade and mainly worked in the fast food industry. I didn’t have much money, but I wanted stuff—so I use credit cards heavily. I got in over my head really fast.

I had been toying with school. I was half-assedly pursuing a philosophy degree, but I wasn’t really putting the effort into that that I should have been. I was unhappy, alone, and going nowhere fast.

At 25 I had a realization—if I met the kind of woman I wanted right then, she would want to have absolutely nothing to do with me. It was a slap in the face. I had this high standard that I expected my future romantic partner to live up to, but I had done nothing to merit her attention. I was a loser.This was my way of judging myself by my own standards. Something had to change.

I had recently seen an article in the newspaper about a high school kid making $50k/year building websites in his spare time. This amount of money seemed unfathomable to me. With that kind of money, I could pay my debts and be on my way. This encouraged me to take some programming classes at the local community college. I had to make some arrangements with my employer so that I could leave work in the middle of the day for classes. I would get to work at 8AM, leave for class around noon, and come back and work until midnight or so. It was hard.

I struggled with nested for-loops in the bubble sort algorithm, but I had a knack for organizing my code in a readable fashion. I managed to get through QBasic, C, and Visual Basic before I decided to submit my resume at the school’s job board.

I got lucky.

It happened that a local company was looking for someone that they wouldn’t have to pay very much and that they could train to work on their software. I had a message on my answering machine from Benny when I got home from school that day.

We scheduled the interview and I showed up with my code-sample—a windows form with a set of radio buttons that toggled an image of a flag for an associated country. I knew it wasn’t much, but I wanted to show that I could do something. I think Benny barely looked at it. The interview actually went well. Benny gave me an overview of the application we would be working on. Their customers were the fast-food industry so my experience there would help a little bit. At least I understood the business domain. After a little probing about my skills, we started talking about “South Park” for another 20 minutes or so. A friendship was born.

Apparently they were desperate. One of my competitors for the job had picked a fight with the secretary before the interview even started! Benny called me a couple of weeks later to tell me that I got the job. I was desperate too. The money wasn’t much—in fact it was a pay cut for me since I would be salaried without overtime compensation. I took the job.

Working with Benny was a revelation. He knew that I didn’t know much, but he also knew that I had a brain in my head and a willingness to learn. He was patient with me while I applied myself and learned to be an effective contributor to our application. My skills grew over time and inside a year I could add to the system almost as easily as he could.

It was 5 years before I managed to pay off my debt. In that time I had learned much about software algorithms, patterns, and practices. I had started my first steps down the road of agile software development practices. I was reading everything I could get my hands on about better ways of writing and managing software. I was evangelizing what I had learned to my co-workers. I started down this path to find a way to pay my bills without filing for bankruptcy. What I found was a passion for a profession that I’m actually pretty good at, and a great new friend.

Benny and I are still friends to this day. We’ve moved on to different jobs, and I moved 3000 miles away to Seattle (I’m hoping to convince him and his wife to move out here!) I shudder to think what might have happened to me had I not been lucky enough to get my start in this field. Getting my foot in the door with him is one of the greatest things that’s ever happened to me.

Thanks Benny.

Isg.EntityFramework 0.5.1 – Release Notes

I’ve added a LookUp property to the InterceptionContext to make it easier to see which rows were affected during the After() interception phase.

    public class InterceptionContext
    {
        public DbContextBase DbContext { get; internal set; }
        public ObjectContext ObjectContext { get; internal set; }
        public ObjectStateManager ObjectStateManager { get; internal set; }
        public DbChangeTracker ChangeTracker { get; internal set; }
        public IEnumerable<DbEntityEntry> Entries { get; internal set; }
        public ILookup<EntityState, DbEntityEntry> EntriesByState { get; internal set; }

... snipped for brevity

EntriesByState is populated prior to the call to Before(). Added and Modified entities will have their EntityState reverted to UnChanged after SaveChanges() is called. EntriesByState preserves the original state of the entities so that After() interceptors can make use of new Id’s and such.

Simple.Validation 0.4.0–Release Notes

New Features

Added an assertion api to the PropertyValidator so that the Properties<T> api can be extended by clients.

The order of operations for the Properties api is as follows: If(), Required(), Assertions().

As an example, customized support for boolean properties was added to the library using the following code:

    public static class BooleanPropertyExtensions
    {
        public static PropertyValidator<TContext, bool> IsTrue<TContext>(this PropertyValidator<TContext, bool>  self)
        {
            self.Assert((t, p) => p);
            return self;
        }

        public static PropertyValidator<TContext, bool> IsFalse<TContext>(this PropertyValidator<TContext, bool> self)
        {
            self.Assert((t, p) => !p);
            return self;
        }

        public static PropertyValidator<TContext, bool?> IsTrue<TContext>(this PropertyValidator<TContext, bool?> self)
        {
            self.Assert((t, p) => p.GetValueOrDefault());
            return self;
        }

        public static PropertyValidator<TContext, bool?> IsFalse<TContext>(this PropertyValidator<TContext, bool?> self)
        {
            self.Assert((t, p) => p.HasValue && !p.Value);
            return self;
        } 
    }

 

Breaking Changes

RangePropertyValidator has been removed. It’s functionality is still available, but it has been entirely replaced by extension methods that use the new Assert() method on the PropertyValidator.

ValidationResultTypes have been completely removed. Then intent for ValidationResult.Type is that it is custom per project.

What’s new in Simple.Validation 0.3.1?

Silverlight 4

The entire Simple.Validation library has been compiled for Silverlight and included in the NuGet package.

Conditional Property Validators

An If() method has been applied to the following property validators:

When If() is called with the required Predicate, the validator will only apply when the condition specified by the Predicate is met.

        [Test]
        public void If_PredicateIsFalse_ShouldNotValidate()
        {
            // Arrange
            var validator = Properties<Employee>
                .For(e => e.Age)
                .GreaterThanOrEqualTo(18)
                .If(e => e.Age != -1)
                ;

            // Act
            var employee = new Employee()
            {
                Age = -1
            };
            var results = validator.Validate(employee);

            // Assert
            Assert.That(results, Is.Empty);

        }
Simple.Validation v0.2.3

A new release of Simple.Validation is available on NuGet.

The changes include:

While Simple.Data is not intended to focus on property-level validation so much that more complex validation scenarios are difficult, it must be recognized that property-level validation accounts for a large part of validation scenarios. In keeping with the goal of simplicity, Simple.Validation provides some mechanisms for wiring up property-level validations quickly. The Fluent Properties API provides factory methods for creating validators for common property types. When used in conjunction with the CompositeValidator<T> it is a trivial task to get simple property-level validation implemented quickly.

This code is from the Personnel.Sample project included in the source code.

    public class SaveAddressValidator : CompositeValidator<Address>
    {
        public override bool AppliesTo(string rulesSet)
        {
            return rulesSet == RulesSets.Crud.Save;
        }

        protected override IEnumerable<IValidator<Address>> GetInternalValidators()
        {
            yield return Properties<Address>.
                For(a => a.Line1)
                .Length(0, 50)
                .Required()
                .Message("Address Line 1 is required.");

            yield return Properties<Address>
                .For(a => a.Line2)
                .Length(0, 50)
                .NotRequired()
                .Message("Line 2 must be between 0 and 50 characters in length.");

            yield return Properties<Address>
                .For(a => a.Line3)
                .Length(0, 50)
                .NotRequired()
                .Message("Line 3 must be between 0 and 50 characters in length.");

            yield return Properties<Address>
                .For(a => a.PostalCode)
                .Length(0, 20)
                .NotRequired()
                .Message("Postal Code must be between 0 and 20 characters in length.");

            yield return Properties<Address>
                .For(a => a.Country)
                .Length(0, 3)
                .NotRequired()
                .Message("Country must be between 0 and 3 characters in length.");

            yield return Properties<Address>
                .For(a => a.StateOrProvince)
                .Length(0, 50)
                .NotRequired()
                .Message("StateOrProvince must be between 0 and 50 characters in length.");

        } 
    }

 

In this sample, each call to Properties<T>.For() returns an instance of StringPropertyValidator. CompositeValidator will accumulate the results from each of the property-level validators and return them all as a single result set. What about non-string properties?

    public class SaveEmployeeValidator : CompositeValidator<Employee>
    {
        public override bool AppliesTo(string rulesSet)
        {
            return rulesSet == RulesSets.Crud.Save;
        }

        protected override IEnumerable<IValidator<Employee>> GetInternalValidators()
        {
            yield return Properties<Employee>
                .For(e => e.FirstName)
                .Length(3, 50)
                .Required()
                .IgnoreWhiteSpace();

            yield return Properties<Employee>
                .For(e => e.LastName)
                .Length(3, 50)
                .Required()
                .IgnoreWhiteSpace()
                ;

            yield return Properties<Employee>
                .For(e => e.Age)
                .MinValue(18)
                .MaxValue(65)
                ;

            yield return Properties<Employee>
                .For(e => e.Address)
                .Required()
                .Cascade("Save")
                ;

            yield return Properties<Employee>
                .For(e => e.ContactInfo)
                .Required()
                .Count(1)
                .Unique<ContactInfo>(c => c.Type)
                .Cascade("Save");

        }
    }

Employee.Age is of type Int32. Properties<T>.For() any property that is convertible to IComparable will return an instance of RangePropertyValidator. If the property is a reference type, it will return an instance of ReferencePropertyValidator, and if it’s a collection type it will return an instance of EnumerablePropertyValidator.

ReferencePropertyValidator and EnumerablePropertyValidator are similar in that they support Cascading validation onto the reference or collection property itself. This means that Valdiator.Validate<T> will be called for the value of the reference property, or for each element of the collection property. The results will be accumulated into the overall validator results.

When performing cascade validation, there is some question about the type that should be passed to Validator.Validate<T>. Should it be the declared property type (or declared type of the elements of the collection), or should Simple.Validation use the actual type of the property value (or collection element). By default, Cascade() uses the actual type of the property value or collection element, but you can specify the usage of a base type or interface by using the Cascade<T> overload.

In the Personnel.Sample project EmailAddress inherits ContactInfo. There is an EmailAddressValidator that tests the email address against a regular expression. If an instance of EmailAddress is added to the Employee.ContactInfo collection, should it be validated using the EmailAddressValidator or the ContactInfoValidator? Calling the non-generic Cascade() method will cause it to be validated using EmailAddressValdiator. Calling Cascade<ContactInfo>() will cause it to be validated only by the SaveContactInfoValidator.

Previous Page · Next Page