source

다중 생성자를 사용한 ASP.NET 코어 종속성 주입

manysource 2023. 6. 9. 22:06

다중 생성자를 사용한 ASP.NET 코어 종속성 주입

ASP.NET Core 응용 프로그램에 여러 생성자가 있는 태그 도우미가 있습니다.이로 인해 ASP.NET 5가 유형을 확인하려고 할 때 런타임에 다음 오류가 발생합니다.

잘못된 작업예외:지정된 모든 인수 유형을 허용하는 여러 생성자가 'MyNameSpace' 유형에 있습니다.'내 태그 도우미'.해당 생성자는 하나만 있어야 합니다.

생성자 중 하나는 매개 변수가 없고 다른 하나는 매개 변수가 등록된 형식이 아닌 일부 인수를 가지고 있습니다.파라미터 없는 생성자를 사용했으면 합니다.

ASP.NET 5 종속성 주입 프레임워크가 특정 생성자를 선택하도록 하는 방법이 있습니까?일반적으로 속성을 사용하여 수행되지만 아무것도 찾을 수 없습니다.

제 사용 사례는 Tag Helper와 HTML Helper 둘 다인 단일 클래스를 만들려고 하는 것인데, 이 문제가 해결되면 완전히 가능합니다.

DI에서 사용할 생성자에 를 적용합니다.

[ActivatorUtilitiesConstructor]
public MyClass(ICustomDependency d)
{
}

을 수행하려면 이위는서를 .ActivatorUtilities your 성생 클스래할▁your▁to를 만듭니다.MyClass. 3으로 .NET Core 3.1을 합니다.ActivatorUtilities이전 버전에서는 수동으로 사용해야 합니다.

services.AddScoped(sp => ActivatorUtilities.CreateInstance<MyClass>(sp));

일리야 말이 맞습니다. 내장 리졸버는 여러 생성자를 노출하는 유형을 지원하지 않습니다.그러나 이 시나리오를 지원하기 위해 대리인을 등록하는 데 방해가 되는 것은 없습니다.

services.AddScoped<IService>(provider => {
    var dependency = provider.GetRequiredService<IDependency>();

    // You can select the constructor you want here.
    return new Service(dependency, "my string parameter");
});

참고: 다른 답변에 나와 있는 것처럼 여러 생성자에 대한 지원이 이후 버전에서 추가되었습니다.이제 DI 스택은 해결할 수 있는 매개 변수가 가장 많은 생성자를 기꺼이 선택할 것입니다.예를 들어 두 개의 생성자(하나는 서비스를 가리키는 매개 변수가 3개이고 다른 하나는 4개인 생성자)가 있는 경우에는 매개 변수가 4개인 생성자를 선호합니다.

ASP.NET Core 1.0 답변

매개 변수가 없는 생성자에 대한 다른 대답은 여전히 참입니다. 즉, 매개 변수가 없는 생성자와 인수가 있는 생성자가 있는 클래스가 있으면 질문의 예외가 느려집니다.

두 개의 생성자에 인수가 있는 경우 동작은 매개 변수가 알려진 첫 번째 일치 생성자를 사용하는 것입니다.의 소스 코드를 볼 수 .ConstructorMatcher자세한 내용은 여기를 참조하십시오.

ASP.NET 핵심 답변

이 문제를 해결/개선할 때까지 다음과 같은 해결 방법을 사용했습니다.

먼저 생성자에 전달된 설정 개체가 null일 수 있음을 고려하여 컨트롤러에서 하나의 생성자만 선언합니다(필요한 구성 설정만 전달). 시작 방법으로 개체를 구성하면 NET Core가 자동으로 주입합니다.

public class MyController : Controller
{
    public IDependencyService Service { get; set; }

    public MyController(IOptions<MySettings> settings)
    {
        if (settings!= null && settings.Value != null)
        {
            Service = new DependencyServiceImpl(settings.Value);
        }
    }
}

그런 다음 테스트 방법에서 두 가지 방법으로 컨트롤러를 인스턴스화할 수 있습니다.

  1. 테스트된 개체를 구성할 때 IOptions 개체 조롱
  2. 모든 매개 변수에 null 전달을 구성한 다음 검정에 사용할 종속성을 스텁합니다.다음은 예입니다.
[TestClass]
    public class MyControllerTests
    {
        Service.Controllers.MyController controller;
        Mock<IDependencyService> _serviceStub;

        [TestInitialize]
        public void Initialize()
        {
            _serviceStub = new Mock<IDependencyService>();
            controller = new Service.Controllers.MyController(null);
            controller.Service = _serviceStub.Object;
        }
    }

이 시점부터 .NET Core에서 종속성 주입 및 조롱을 통해 전체 테스트를 수행할 수 있습니다.

도움이 되길 바랍니다.

Azure 함수 .NET 7 분리

Kévin Chalet 답변을 기반으로, 만약 당신이 zure 기능을 사용하고 있다면, 당신은 GetService 기능을 호출할 수 있습니다.

var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(s =>    {
    
    s.AddHttpClient(); 
    s.AddSingleton<DataLookup>(l => { 

        var dependency = l.GetService<IHttpClientFactory>();

        return new DataLookup(dependency);
    });
})
.Build();

언급URL : https://stackoverflow.com/questions/32931716/asp-net-core-dependency-injection-with-multiple-constructors