Рассмотрим подход отражения.
Просто пометьте конструкторы классов как частные, чтобы их нельзя было создавать обычным способом, и ваша фабрика будет вызывать этот конструктор закрытого класса с помощью отражения.
Отражение влияет на производительность, но вызов этого конструктора не является большой операцией отражения.
Проверьте эту статью MSDN, чтобы узнать больше о том, как вызвать приватный конструктор с помощью отражения:
Но его можно обобщить следующим фрагментом кода:
typeof(T).GetConstructor(BindingFlags.Instance | BindingFlags.Private, Type.EmptyTypes, Type.DefaultBinder, null).Invoke(null);
UPDATE
Кстати, я считаю, что любое влияние на производительность и усложнение кода, потому что вы не хотите, чтобы разработчики создавали экземпляр класса, делая это только с помощью такого фабричного метода, не является серьезной причиной.
Иногда хорошие рекомендации разработчиков лучше, чем любое ограничение кода. Я говорю это потому, что в вашем случае я бы реализовал этот метод фабрики с универсальным параметром T и тем же общим ограничением, и я, если в моих документах сказано: «если вам нужен экземпляр типа T, вам нужно использовать эту фабрику» и некоторые решают не следовать этому правилу, это не будет моей обязанностью, и на любую проблему с этим ответят: «В руководстве сказано, что вам нужно использовать завод».
Хорошие привычки лучше, чем дополнительный защитный код, для принятия человеческих решений.