Olá, Lucas
Sim, é possível, e a solução para isso é pensar num bom projeto de arquitetura de software. Eu não sei exatamente que tipo de projetos você tem em mente, então vou colocar aqui várias ideias.
Imagino que você queira manter vários projetos (um para cada cliente) construídos sobre o mesmo projeto-base, certo?
O que você pode fazer é:
- Definir o que é o projeto-base
- Quais são as regras de negócio comuns a todos os projetos?
- Quais são os modelos comuns a todos os projetos?
- Quais são os controllers comuns a todos os projetos?
- Quais são as telas/páginas/views comuns a todos os projetos?
O .Net Core recentemente introduziu o conceito de "Razor Class Libraries", que permite empacotar os seus componentes do front-end (Model, View, e Controllers) para que você possa reutilizá-los em diversos projetos.
https://docs.microsoft.com/en-us/aspnet/core/razor-pages/ui-class?view=aspnetcore-2.1&tabs=visual-studio
Além de usar Razor Class Libraries, você deve quebrar sua solução em diversos projetos no back-end, para não misturar o código do projeto-base com os projetos custom. Por exemplo, digamos que você esteja criando um web app para controle de estoque da "Loja do Zezinho", mas quer usar um projeto-base que possa ser reaproveitado em outros projetos. Você poderia ter:
- Projeto ControleEstoque.UI.Base.csproj (Razor Class Libraries - Front End)
- Projeto ControleEstoque.UI.LojaDoZezinho.csproj (MVC - Front End)
- Projeto ControleEstoque.RegrasNegocio.Base.csproj (Class Library - Back End)
- Projeto ControleEstoque.RegrasNegocio.LojaDoZezinho.csproj (Class Library - Back End)
Agora, o que é o projeto-base e o que é específico da Loja do Zezinho? Isso depende do que você considera, por exemplo, como "regra geral" e como "regra da Loja do Zezinho". Normalmente, você só terá uma boa ideia sobre essa diferença se conhecer bem o mercado, ou quando aparecerem mais clientes do seu projeto de controle de estoque.
Além disso, pesquise sobre estes conceitos:
- Separação de Responsabilidades
- Princípio Open-Closed: significa que uma classe deve ser aberta para extensão, mas fechada para modificação. Isto é, deixe uma class tão bem definida que qualquer mudança nela seja desnecessária. Se você precisar modificar seu funcionamento, utilize herança, polimorfismo ou métodos de extensão
- classe-base, modificadores virtual e override
- O padrão de projeto (design pattern) chamado Template Method, que é muito usado nesse tipo de projeto
- Injeção de dependência (e Inversão de controle). O ASP.NET Core já vem com essa funcionalidade embutida. Veja como criar instâncias a partir de interfaces.
- Programação com interfaces
Enfim, tem muito assunto para tratar, e estudar, dependendo do que você já sabe sobre ASP.NET Core e do tipo de projeto que você tem em mente. O que você acha?