C# .Net Core 依赖注入(inject),向构造函数注入(inject)多个参数

标签 c# .net dependency-injection constructor .net-core

我有 AuthenticationStrategy 类,我将把它注入(inject)到 Controller 构造函数中。

我有两个 IAuthenticationProvider:InternalAuthenticationProviderExternalAuthenticationProvider
AuthenticationStrategy 构造函数中,我想注入(inject)所有提供程序。
示例代码:

public class AuthenticationStrategy
{
    private readonly Dictionary<string, IAuthenticationProvider> _authenticationProviders;

    public AuthenticationStrategy(IAuthenticationProvider[] authenticationProviders)
    {
        if (authenticationProviders == null)
        {
            throw new ArgumentNullException("AuthenticationProviders");
        }

        _authenticationProviders = authenticationProviders
            .ToDictionary(x => nameof(x), x => x);
    }
}

如何使用依赖注入(inject)注入(inject)多个提供者? 示例代码:

services.AddScoped<IAuthenticationProvider, InternalAuthenticationProvider>();
services.AddScoped<IAuthenticationProvider, ExternalAuthenticationProvider>();
services.AddScoped<AuthenticationStrategy>();

有什么想法吗?

最佳答案

我认为将 Dictionary 存储在您的策略中是一种代码味道,因为它看起来像一个反模式 Service Locator。您可能需要 introduce the factory基于 key 的身份验证提供程序。这是 .Core 依赖注入(inject)中的理想方法,但是您可以使用其他 IoC containers with similar features (例如,命名依赖项)。

所以,你的代码可能是这样的:

public enum AuthType
{
    Internal,
    External,
}

public interface IAuthenticationProviderResolver
{
    IAuthenticationProvider GetAuthByType(AuthType type);
}

public class ProviderResolver : IAuthenticationProviderResolver
{
    private readonly IServiceProvider _serviceProvider;

    public RepositoryResolver(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public IAuthenticationProvider GetAuthByName(AuthType type)
    {
         switch (type) 
         {
             case AuthType.Internal:
                 return _serviceProvider.GetService<InternalAuthenticationProvider>();
             case AuthType.External:
                 return _serviceProvider.GetService<ExternalAuthenticationProvider>();
             default:
                 throw new ArgumentException("Unknown type for authentication", nameof(type))
         }
    }
}

现在您只需像往常一样注册您的类(class):

services.AddSingleton<IAuthenticationProviderResolver, ProviderResolver>();
services.AddScoped<InternalAuthenticationProvider>();
services.AddScoped<ExternalAuthenticationProvider>();
services.AddScoped<AuthenticationStrategy>();

以及策略中的用法:

public class AuthenticationStrategy
{
    private readonly IAuthenticationProviderResolver _resolver;

    public AuthenticationStrategy(IAuthenticationProviderResolver resolver)
    {
        if (resolver== null)
        {
            throw new ArgumentNullException("Provider Resolver");
        }

        _resolver = resolver;
    }

    public void MakeDecision()
    {
        _resolver.GetAuthByType(authType).Authenticate();
    }
}

关于C# .Net Core 依赖注入(inject),向构造函数注入(inject)多个参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43063084/

相关文章:

c# - 在 Debug模式下观察变量时出现 FileNotFoundException

c# - 在递归中使用 Math.Pow() 时,超出了 C# 的执行时间限制

c# - IScheduler.Schedule 与 IScheduler.ScheduleAsync?

c# - 领域特定语言 (DSL) 和领域驱动设计 (DDD)

.net - 编写正则表达式来捕获外括号之间的文本

c# - 扩展 C# 中的现有结构以添加运算符

.net - 我应该使用字符串常量还是字符串文字

PHP 依赖注入(inject) - Pimple 等。 - 为什么使用关联数组与 getter?

java - 需要模式建议(Hibernate + Guice)

c# - ASP.NET Core 如何让 UserManager 在 Controller 中工作?