Então o Autofac nos permite selecionar qual construtor usar caso o tipo concreto registrado tenha múltiplos candidatos. É explicado aqui - https://autofac.readthedocs.io/en/latest/advanced/constructor-selection.html#iconstructorselector
Mas e se eu quiser usar meu seletor de construtor personalizado para cada registro do qual tenho bastante (milhares em várias centenas de Autofac.Module
classes)? Como posso alterar o padrão sem personalizar explicitamente cada registro?
Motivação
Temos um aplicativo .NET Framework muito grande usando MEF como IoC. Queremos substituí-lo pelo Autofac como uma etapa preliminar antes de migrar para o .NET Core.
Existe o Autofac.Mef, mas ele não suporta injeção Lazy ou de genéricos abertos, conforme a documentação aqui - https://autofac.readthedocs.io/en/latest/integration/mef.html#known-issues-gotchas
Portanto, migraremos para o Autofac propriamente dito. Já escrevi um código que inspeciona o contêiner MEF criado e gera o respectivo código de registro do Autofac. Mas há um problema - e se o Autofac selecionar um construtor diferente do MEF? Ou seja, não aquele atribuído com [ImportingConstructor]
?
Portanto, eu gostaria de poder personalizar o código de registro para respeitar o atributo, pelo menos por enquanto, para reduzir o risco de regressão. Claro, já que o código é gerado de qualquer forma, eu posso modificar todo e qualquer registro. Mas eu me pergunto se há uma maneira melhor.
Não há uma maneira realmente boa de fazer isso.
Grande parte do desafio está na combinação da sintaxe do construtor/retornos de chamada usados, bem como na natureza dinâmica das coisas que o Autofac fornece com conceitos como fontes de registro.
Quando você registra coisas ( como
RegisterType<T>()
), ele adiciona uma única função de retorno de chamada aoContainerBuilder
. O conjunto geral de funções de registro encadeadas é executado no final, duranteBuild()
É uma espécie de construção de uma cadeia de middleware de retorno de chamada para retorno de chamada para retorno de chamada que acaba construindo um registro de objeto completo. Não há um lugar real para "interceptá-los globalmente".Apresentar algo "global" tem algumas implicações que não são muito fáceis de abordar, e é por isso que algo assim não existe.
Colocar um conjunto rápido de opções no
ContainerBuilder
é, claramente, uma coisa muito fácil de fazer. Só que o efeito cascata de "mudar o comportamento global" traz uma tonelada com ele, então não fizemos isso.Dito isso, se isso for algo interessante, eu o encorajaria a abrir um problema e propô-lo . Se fizer isso, certifique-se de incluir o design proposto para todas as pequenas partes de longo alcance, como mencionei. A equipe é pequena e projetar novos recursos de linguagem como esse requer que a comunidade contribua com o trabalho braçal. (Temos um problema para um global
IPropertySelector
com uma solicitação semelhante, mas não há design e não há uma ótima maneira de lidar com isso.)Adendo: Embora eu não possa iterar sobre soluções, direi o seguinte:
Com base no objetivo de forçar um construtor específico devido a essa migração do MEF, se fosse eu, eu iria e...
Entendo que isso pode estar banalizando o problema, mas migrar do MEF não dá trabalho nenhum, assim como migrar do WCF para o ASP.NET Core não dá trabalho nenhum.
Mas como eu disse, se fosse EU, é assim que eu faria.