Esse é um caso de uso típico para o COI?
Meu aplicativo atual permite que os usuários definam formulários da Web personalizados por meio de um conjunto de telas de administração. é essencialmente um aplicativo do tipo EAV. Como tal, não consigo codificar a marcação HTML ou ASP.NET para renderizar uma determinada página. Em vez disso, a interface do usuário solicita uma instância de um objeto Form da camada de serviço, que por sua vez cria uma usando várias tabelas RDMBS. O formulário contém o tipo de classe que você esperaria ver nesse contexto:Form
=>IEnumerable<FormSections>
=>IEnumerable<FormFields>
Aqui está a aparência da camada de serviço:
public class MyFormService: IFormService{
public Form OpenForm(int formId){
//construct and return a concrete implementation of Form
}
}
Tudo funciona esplendidamente (por um tempo). A interface do usuário não é mais sábia sobre quais seções / campos existem em um determinado formulário: ela processa felizmente o objeto Form que recebe em uma página ASP.NET funcional.
Algumas semanas depois, recebo um novo requisito da empresa: ao exibir versões não editáveis (isto é, somente leitura) de um formulário, certos valores de campo devem ser mesclados e outros campos calculados / inventados devem ser adicionados. Não tem problema, eu digo. Simplesmente altere minha classe de serviço para que seus métodos sejam mais explícitos:
public class MyFormService: IFormService{
public Form OpenFormForEditing(int formId){
//construct and return a concrete implementation of Form
}
public Form OpenFormForViewing(int formId){
//construct and a concrete implementation of Form
//apply additional transformations to the form
}
}
Novamente, tudo funciona muito bem e o equilíbrio foi restaurado à força. A interface do usuário continua sendo independente do que está no formulário e nossa separação de preocupações é alcançada. Apenas algumas semanas depois, no entanto, a empresa lança um novo requisito: em certos cenários, devemos aplicar apenasalguns das transformações de formulário que referenciei acima.
Neste ponto, parece que a abordagem "método explícito" atingiu um beco sem saída, a menos que eu queira acabar com uma explosão de métodos (OpenFormViewingScenario1, OpenFormViewingScenario2, etc.). Em vez disso, apresento outro nível de indireção:
public interface IFormViewCreator{
void CreateView(Form form);
}
public class MyFormService: IFormService{
public Form OpenFormForEditing(int formId){
//construct and return a concrete implementation of Form
}
public Form OpenFormForViewing(int formId, IFormViewCreator formViewCreator){
//construct a concrete implementation of Form
//apply transformations to the dynamic field list
return formViewCreator.CreateView(form);
}
}
Na superfície, isso parece uma abordagem aceitável e ainda existe um certo cheiro. Ou seja, a interface do usuário, que vivia em êxtase ignorante sobre os detalhes de implementação do OpenFormForViewing, deve possuir conhecimento e criar uma instância do IFormViewCreator.
Minhas perguntas são duplas: Existe uma maneira melhor de alcançar a composibilidade que eu procuro? (talvez usando um contêiner de IoC ou uma fábrica de laminados em casa para criar o IFormViewCreator concreto)?Estraguei fundamentalmente a abstração aqui?