API modular da Web do ASP.NET: como adicionar / remover rotas em tempo de execução a uma API da Web
Estou tentando criar um aplicativo de API da Web modular (não é um aplicativo MVC!) No qual um usuário na função de administrador pode adicionar ou remover módulos sem reiniciar o aplicativo ASP.NET.
Módulo: cada módulo é um assembly (arquivo .dll) que contém pelo menos uma classe derivada deApiController
.O roteamento é baseado emRoteamento de Atributos na API da Web do ASP.NET 2A produção de módulos (montagens) não está no escopo desta questão.Módulos (arquivos de montagem) são copiados para / excluídos da pasta `~ / plugins / na raiz do projeto. Esse processo também não está no escopo desta pergunta.O principal projeto da API da Web do ASP.NET possui basicamente apenas um controlador para gerenciar (adicionar / remover) módulos. Os outros controladores serão adicionados como módulos.Portanto, o único controlador no projeto principal da API da Web é:
[RoutePrefix("api/modules")]
public class ModulesController : ApiController
{
private ModuleService _moduleService = new ModuleService();
// GET: api/Modules
[Route]
public IEnumerable<string> Get()
{
return _moduleService.Get().Select(a => a.FullName);
}
// POST: api/Modules/{moduleName}
[Route("{id}")]
public void Post(string id)
{
Assembly _assembly;
var result = _moduleService.TryLoad(id, out _assembly);
if(!result) throw new Exception("problem loading " + id);
// Refresh routs or add the new rout
Configuration.Routes.Clear();
Configuration.MapHttpAttributeRoutes();
// ^ it does not work :(
}
// DELETE: api/Modules/{moduleName}
[Route("{id}")]
public void Delete(string id)
{
_moduleService.Remove(id);
}
}
ModuleService.TryLoad()
simplesmente localiza e carrega o assembly no domínio do aplicativo usandoAppDomain.CurrentDomain.Load()
. Esta parte está funcionando bem.
Configuration.MapHttpAttributeRoutes()
não gera nenhum erro, mas quebra todo o sistema de roteamento. Após essa linha, qualquer tentativa de roteamento causa este erro:
O objeto ainda não foi inicializado. Verifique se HttpConfiguration.EnsureInitialized () é chamado no código de inicialização do aplicativo após todos os outros códigos de inicialização.
Eu adicioneiHttpConfiguration.EnsureInitialized()
para o código, mas não resolveu o problema (mesmo erro).