Pergunta

Sou novo em zombar e injeção de dependência e preciso de algumas orientações.

Meu aplicativo está usando uma arquitetura típica de N-Tier, onde o BLL faz referência ao DAL, e a interface do usuário faz referência ao BLL, mas não ao DAL. Bem direto.

Digamos, por exemplo, eu tenho as seguintes aulas:

class MyDataAccess : IMyDataAccess {}
class MyBusinessLogic {}

Cada um existe em uma montagem separada.

Quero zombar do mydataaccess nos testes para o MyBusinessLogic. Por isso, adicionei um construtor à classe MybusinessLogic para obter um parâmetro imydataaccess para a injeção de dependência. Mas agora, quando tento criar uma instância do MyBusinessLogic na camada da interface do usuário, é necessário uma referência ao DAL.

Eu pensei que poderia definir um construtor padrão no MyBusinessLogic para definir uma implementação padrão do IMYDATAACC, mas isso não apenas parece um código de código, ele realmente não resolveu o problema. Eu ainda teria um construtor público com imydataacccess na assinatura. Portanto, a camada da interface do usuário ainda requer uma referência ao DAL para compilar.

Uma solução possível com a qual estou brincando é criar um construtor interno para o MyBusinessLogic com o parâmetro iMydataAccess. Em seguida, posso usar um acessador do projeto de teste para ligar para o construtor. Mas ainda há esse cheiro.

Qual é a solução comum aqui. Eu devo estar apenas fazendo algo errado. Como eu poderia melhorar a arquitetura?

Foi útil?

Solução

Você pode definir suas aulas como esta:

public class MainForm : Form
{
    private readonly businessLogic;

    public MainForm(IBusinessLogic businessLogic)
    {
        this.businessLogic = businessLogic;
    }
}

public class BusinessLogic : IBusinessLogic
{
    private IDataLayer dataLayer;

    public BusinessLogic(IDataLayer dataLayer)
    {
        this.dataLayer = dataLayer;
    }
}

public class DataLayer : IDataLayer
{
    public DataLayer(string connectionString)
    {
    }
}

Observe como o formulário principal não sabe sobre o dal aqui. Agora precisamos de um pedaço de código que conheça todas as classes, para que elas possam ser conectadas. Isso geralmente é feito no início do aplicativo:

public static void Main(string[] args)
{
   var dataLayer = new DataLayer("foo");
   var businessLogic = new BusinessLogic(dataLayer);
   var mainForm = new MainForm(businessLogic);

   Application.Run(mainForm);
}

Obviamente, este é um exemplo simplificado. Se você tiver dezenas ou centenas de aulas na prática, essa fiação inicial pode ficar muito grande e complicada, especialmente quando as dependências cíclicas entram em jogo. É por isso que estruturas de injeção de dependência foram criadas para substituir esse código por arquivos de configuração XML, configuração por código ou atributos .NET. A ideia básica é a mesma.

Exemplos de estruturas de injeção de dependência para .NET: Autofac, Castelo, Spring.net, StructureMap, Ninject e a Estrutura de extensibilidade gerenciada.

Outras dicas

EU respondidas uma pergunta ontem sobre como estrutura uma solução .NET que eu acho que resolverá seu problema.

O ponto principal para você, na minha resposta, deve ser que nenhum dos conjuntos de "implementação" tenha referências a outras montagens de "implementação". Isso deve resolver sua separação de questões de preocupações.

Além disso, a estrutura também quase exige o uso da injeção de dependência e é muito adequada para testes de unidade e o uso da zombaria.

Espero que ajude.

Se você deseja evitar fazer referência à DLL de acesso a dados da DLL da interface do usuário, poderá extrair as interfaces de acesso a dados/classes de base para uma terceira biblioteca e ter as outras duas referências.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top