What would be alternative ways to model IConvention? public class Item { /*...*/ }
public class Model { /*...*/ }

public interface IConventionInstanceSelector {
  IConventionInstance Select(Item item);
}

public interface IConventionInstance {
  void ApplyTo(Model model);
}

public interface IConvention {
  bool IsMatchedBy(Item item);
  IConventionInstance CreateInstance(Item item);
}

public class ConventionInstanceSelector : IConventionInstanceSelector {
  readonly List&lt;IConvention&lt;Item&gt;&gt; _conventions;

  public ConventionInstanceSelector(IEnumerable&lt;IConvention&lt;Item&gt;&gt; conventions) {
    _conventions = conventions.ToList();
  }

  public IConventionInstance Select(Item item) {
    foreach(var convention in _conventions) {
      if(convention.IsMatchedBy(item)) {
        return convention.CreateInstance(item);
      }
    }
    return NullConventionInstance.Instance;
  }
}

public class ModelReader {
  IConventionInstanceSelector _selector;

  public ModelReader(IConventionInstanceSelector selector) {
    _selector = selector;
  }

  public Model Read(IEnumerable&lt;Item&gt; items) {
    var model = new Model();
    foreach(var item in items) {
      _selector.Select(item).ApplyTo(model);    
    }
    return model;
  }
}


I'm a bit concerned about the specification and factory method  being merged into one interface (IConvention) and that they can be called separately when in fact one depends on the decision of the other. I also get the feeling there's a pattern here I'm not seeing.

Just to give a little bit more context: I'm trying to build an API whereby people can build their own conventions that get applied to an input stream (an enumeration of items in this case) and have each convention apply a transformation on the input (the item in this case) and add it to a model. The main concern is the convention represents both the fact an item satisfies the convention as well as the logic to apply it to the model AND the fact that how I've modeled it right now, those are two distinct operations whereby the latter relies on the first to be able to do it's job properly. It's like specification pattern meets factory pattern.
First of all, the combination of a Specification and another method is not that unusual - it's called the Tester-Doer Pattern (although to be fair, I'm not sure whether it's a bona-fide pattern, as I've never seen it described outside of .NET). Even so, despite the precedence, I completely understand why you dislike the Temporal Coupling it implies. So which alternatives are available?

The first refactoring we could apply is to change the definition of IConvention to emply a Maybe monad. Assuming that we've defined a Maybe&lt;T&gt; class, IConvention now looks like this:

public interface IConvention
{
    Maybe&lt;IConventionInstance&gt; CreateInstance(Item item);
}


This would allow you to in a type-safe way to check whether or not an IConventionInstance instance could be created from the item.

However, once you realize that a Maybe monad really is nothing more than a special case of IEnumerable, you could consider refactoring IConvention once more:

public interface IConvention
{
    IEnumerable&lt;IConventionInstance&gt; CreateInstances(Item item);
}


In the normal implementation, an implementation would return zero or one item.

This would make the ConventionInstanceSelector and IConventionInstanceSelector types redundant (always a good thing), and you could implement the ModelReader class like this (caveat: I haven't tried to compile it):

public class ModelReader {
    IEnumerable&lt;IConvention&gt; _conventions;

    public ModelReader(IEnumerable&lt;IConvention&gt; _conventions) {
        _conventions = conventions;
    }

    public Model Read(IEnumerable&lt;Item&gt; items) {
        var model = new Model();

        var conventionInstances = from item in items
                                  from c in _conventions
                                  from ci in c.CreateInstances(item)
                                  select ci;
        foreach(var ci in conventionInstances) {
            ci.ApplyTo(model);
        }

        return model;
    }
}