First of all, I apologise for the vagueness of the question title and if this has been asked elsewhere already. I struggled to find a similar answer due to the amount of other 'what is this pattern called' questions.
I've got the following abstract class:
public abstract class PositionProvider<T> : DalProvider<T>, IDalProvider 
    where T : IPositionEntity
{
    protected PositionProvider()
        : base() { }
    public RP_PositionType PositionType
    {
        get
        {
            return _positionType;
        }
    }
    private RP_PositionType _positionType;
    public abstract List<T> GetList();
    internal void SetPositionType(RP_PositionType positionType)
    {
        if (_positionType == null)
        {
            _positionType = positionType;
        }
        else
        {
            throw new NotSupportedException(
                "PositionType can only be set once.");
        }
    }
}
I've then got a concrete implementation of this class:
public class SqlPositionProvider<T> 
    : PositionProvider<T> where T : IPositionEntity
{
    public override List<T> GetList()
    {
        int positionTypeId = (int)this.PositionType;
        // Return the matching items here
    }
}
This is then utilised by a number of different 'item' classes, such as the following, but replacing CustomerEntity with SiteEntity/MajorEntity/MinorEntity:
public class CustomerProvider
{
    public static PositionProvider<CustomerEntity> Instance
    {
        get
        {
            if (_instance == null)
            {
                DalHelper.CreateInstance<PositionProvider<CustomerEntity>>(
                    out _instance);
                _instance.SetPositionType(RP_PositionType.Customer);
            }
            return _instance;
        }
    }
    private static PositionProvider<CustomerEntity> _instance;
}
The CustomerProvider, SiteProvider, etcProvider are all just hold a specific instance of the PositionProvider class. The only difference between them is the entity type and the RP_PositionType enum. This is so I can use the same Sql concrete implementation within GetList() to pull back all records from a particular table based on the PositionType (PositionTypeId when the enum is converted to an int value).