AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79413267
Accepted
mark
mark
Asked: 2025-02-05 07:17:43 +0800 CST2025-02-05 07:17:43 +0800 CST 2025-02-05 07:17:43 +0800 CST

Como instalar a implementação padrão do IConstructorSelector para ser usada em todo e qualquer registro

  • 772

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.Moduleclasses)? 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.

autofac
  • 1 1 respostas
  • 19 Views

1 respostas

  • Voted
  1. Best Answer
    Travis Illig
    2025-02-06T04:58:16+08:002025-02-06T04:58:16+08:00

    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 ( comoRegisterType<T>() ), ele adiciona uma única função de retorno de chamada ao ContainerBuilder. 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.

    • Você pode registrar coisas novas em escopos de tempo de vida filho. Todos eles devem usar o mesmo seletor de construtor global? E se você quiser substituir o seletor de construtor apenas para esse escopo de tempo de vida? Se você substituir o seletor no escopo de tempo de vida, isso também leva em conta todos os registros que foram registrados em um escopo de tempo de vida pai ou isso agora altera esses registros pais?
    • Como lidamos com coisas como fontes de registro que adicionam registros dinamicamente por meio de, digamos, varredura de assembly? Elas obedecem ao seletor global? Como aplicamos isso em fontes personalizadas que as pessoas escrevem?
    • Se, em vez disso, permitíssemos que o middleware modificasse o localizador ou seletor do construtor no momento da resolução (que é um possível ponto de conexão para algo assim), como isso começaria a afetar coisas como singletons ou entidades de escopo de instância por tempo de vida?
    • Como fornecemos suporte/observabilidade para ajudar as pessoas em grandes projetos a solucionar problemas quando isso dá errado? Alguém em algum lugar definiu um seletor de construtor personalizado, outra pessoa não sabe onde está esse código, agora todos os registros estão quebrados e "Autofac está quebrado, o que vocês, caras da Autofac, fizeram?"

    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 globalIPropertySelector 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...

    1. Encontre todos os objetos que têm mais do que apenas um construtor de 0 parâmetros e múltiplos parâmetros. Esses serão aqueles em que você acha que precisa mirar em alguma coisa específica. Pode não ser tanto. Você pode estar tentando resolver um problema em que há apenas 3 classes ofensivas. Se for esse o caso, registre o seletor em linha. Exceto isso...
    2. Ou remova os construtores que você não quer que o Autofac considere ou torne-os internos. Em um sistema DI padrão, você realmente tenta evitar ter um monte de construtores especificamente para contornar esse problema de seleção.

    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.

    • 0

relate perguntas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve