No MVC, tento garantir que meu controlador seja o mais "fino" possível e também que meus modelos sejam o mais burros possível.
As funções lógicas e auxiliares necessárias são colocadas em classes auxiliares separadas e independentes. Isso torna meus testes muito mais fáceis também (você está testando ... certo?: D) Testar controladores é notoriamente difícil, sempre que você tenta criar uma instância de um controlador para testar, você precisa pensar no contexto HTTP e na falsificação http isto e aquilo, e é uma dor, mas é uma dor de propósito. Você precisa de tudo isso porque um controlador está intimamente ligado ao HTTP e à Web. É o ponto de entrada para o seu aplicativo da web.
As funções de lógica e auxiliar não têm nada a ver com a web. Eles são totalmente independentes do ambiente (ou deveriam ser). Só isso deve lhe dizer que eles não pertencem um ao outro no mesmo lugar. Além disso, se você vincular todas as lógicas de seus aplicativos tão intimamente à Web ou a uma implementação específica da Web, nunca poderá levá-la consigo.
Desenvolvemos nosso site MVC com todas as nossas entidades de banco de dados (não nossos modelos mvc, nossas entidades db reais), nosso armazenamento, nossas classes auxiliares e nossa lógica em dlls independentes e independentes. Todos nós possuímos apenas um site, mas fizemos assim de qualquer maneira.
Alguns meses atrás, fomos solicitados a criar alguns aplicativos de desktop relacionados a alguns de nossos sistemas adicionais. Isso foi feito facilmente, pois todo o nosso código testado poderia ser facilmente reutilizado. Se tivéssemos introduzido nosso código em nosso projeto da Web ou colocado em nossos controladores, nunca conseguiríamos fazer isso.