4
respostas

[Dúvida] Poque eu não precisei passar a ass. do código?

Vi que no de vocês é colocado o "adopet" como parâmetro do método ao criar uma instância de HttpClient, mas no meu não foi preciso. E pra ajudar, ao modificar o método para receber esse parâmetro ele estava dando erro na interface IHttpClientFactory.

Seria por conta da versão do IHttpClientFactory? Se sim, como eu poderia passar uma ass. para ele ou várias ass. em um caso futuro?

using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System;
using System.Net.Http.Headers;

namespace Alura.Adopet.Console.Servicos;

internal class AdopetAPIClientFactory : IHttpClientFactory
{
    private string url = "http://localhost:5057";

    public HttpClient GetHttpClient()
    {
        HttpClient _client = new HttpClient();
        _client.DefaultRequestHeaders.Accept.Clear();
        _client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
        _client.BaseAddress = new Uri(url);
        return _client;
    }
}
4 respostas

Oi Igor! Como vai?

Isso pode estar relacionado à forma como a interface IHttpClientFactory foi projetada para funcionar, permitindo a criação de diferentes clientes configurados para diferentes casos de uso, como mencionado na documentação que você está seguindo.

Quando você utiliza IHttpClientFactory, a ideia é que você possa nomear diferentes configurações de HttpClient e, ao chamar CreateClient("nome"), você obtém uma instância configurada de acordo com o que foi definido para aquele nome. No seu caso, parece que o nome "adopet" está sendo usado para identificar uma configuração específica, mesmo que no momento não haja diferença prática.

Sobre o erro que você mencionou ao tentar modificar o método para receber esse parâmetro, pode ser que a assinatura do método CreateClient não tenha sido implementada corretamente na sua classe AdopetAPIClientFactory. A interface IHttpClientFactory espera que o método CreateClient receba um parâmetro name do tipo string. Certifique-se de que sua implementação está de acordo com essa assinatura.

Para passar várias assinaturas no futuro, você pode criar diferentes implementações de HttpClient dentro da sua fábrica, cada uma com um nome distinto. Por exemplo:

public HttpClient CreateClient(string name)
{
    if (name == "adopet")
    {
        // Configurações específicas para "adopet"
    }
    else if (name == "outroCliente")
    {
        // Configurações específicas para "outroCliente"
    }
    // Adicione mais condições conforme necessário
    throw new ArgumentException("Cliente não configurado", nameof(name));
}

Espero que isso ajude a esclarecer sua dúvida!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.

Então, quando eu passa pra ele uma string, ele dá erro na interface como se eu não tivesse implementado o método.

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Código com erro:

using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Net.Http.Headers;

namespace Alura.Adopet.Console.Servicos;

public class AdopetAPIClientFactory : IHttpClientFactory // Aqui onde está o erro
{
    private string url = "http://localhost:5057";

    public HttpClient CreateClient(string name)
    {
        if(name == "AdopetAPI")
        {
            HttpClient _client = new HttpClient();
            _client.DefaultRequestHeaders.Accept.Clear();
            _client.DefaultRequestHeaders.Accept.Add(
                new MediaTypeWithQualityHeaderValue("application/json"));
            _client.BaseAddress = new Uri(url);
            return _client;
        }
        
        return new HttpClient();
    }
}

Código sem erro:

using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Net.Http.Headers;

namespace Alura.Adopet.Console.Servicos;

public class AdopetAPIClientFactory : IHttpClientFactory
{
    private string url = "http://localhost:5057";

    public HttpClient GetHttpClient()
    {
        HttpClient _client = new HttpClient();
        _client.DefaultRequestHeaders.Accept.Clear();
        _client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
        _client.BaseAddress = new Uri(url);
        return _client;
    }
}

Isso que eu não entendi direito, porque essa IHttpClientFactory vem de uma Lib, que foi passada no curso. Então eu achei que ela teria essa implementação para nenhuma, para uma ou N's ass. assim, como eu poderia passar pelo menos uma ass.?

A classe de teste está assim:

using Alura.Adopet.Console.Comandos;
using Alura.Adopet.Console.Modelos;
using Alura.Adopet.Console.Servicos;
using Alura.Adopet.Console.Util;
using Moq;

namespace Alura.Adopet.Testes;

public class ImportTeste
{
    [Fact]
    public async Task QuandoApiEstaNoArDeveRetornarListaDePet()
    {
        var leitorDeArquivo = new Mock<LeitorDeArquivo>(MockBehavior.Default, It.IsAny<string>());
        var listaDePets = new List<Pet>();
        var pet = new Pet(new Guid("456b24f4-19e2-4423-845d-4a80e8854a41"), "Lima", TipoPet.Cachorro);
        listaDePets.Add(pet);

        leitorDeArquivo.Setup(x => x.RealizaLeitura("")).Returns(listaDePets);

        var httpClientPet = new HttpClientPet(new AdopetAPIClientFactory().GetHttpClient());
        var import = new Import(httpClientPet, leitorDeArquivo.Object);
        string[] args = { "import", "lista.csv" };
        //Act
        await import.ExecutaAsync(args);
        //Assert 
        var listaPet = await httpClientPet.ListPetsAsync();
        Assert.NotNull(listaPet);

    }
}

Mas está dando esse erro:

 Message: 
System.ArgumentException : Can not instantiate proxy of class: Alura.Adopet.Console.Util.LeitorDeArquivo.
Could not find a constructor that would match given arguments:
<null>
 (Parameter 'constructorArguments')
---- System.MissingMethodException : Constructor on type 'Castle.Proxies.LeitorDeArquivoProxy' not found.

  Stack Trace: 
ProxyGenerator.CreateClassProxyInstance(Type proxyType, List`1 proxyArguments, Type classToProxy, Object[] constructorArguments)
ProxyGenerator.CreateClassProxy(Type classToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, Object[] constructorArguments, IInterceptor[] interceptors)
CastleProxyFactory.CreateProxy(Type mockType, IInterceptor interceptor, Type[] interfaces, Object[] arguments) line 62
Mock`1.InitializeInstance() line 309
Mock`1.OnGetObject() line 323
Mock.get_Object() line 179
Mock`1.get_Object() line 281
ImportTeste.QuandoApiEstaNoArDeveRetornarListaDePet() line 24
--- End of stack trace from previous location ---
----- Inner Stack Trace -----
RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture)
ProxyGenerator.CreateClassProxyInstance(Type proxyType, List`1 proxyArguments, Type classToProxy, Object[] constructorArguments)

Segue o meu GitHub: https://github.com/IgorTudisco/Boas_Praticas-CSharp