基于条件的Autofac 5中止寄存器

问题描述 投票:0回答:1

对于一个应用程序,我有多个IAuthentificationProvider:

public interface IAuthentificationProvider
{
   bool IsUserValid(string login, string password)
}

对于每个IAuthentificationProvider,我都有一个IAuthentificationProviderConfig与以下内容关联:

public interface IAuthentificationProvider
{
   bool IsEnabled { get; set; }
}

要使用所有这些启用的提供程序,我还有另一个课程:

public class AuthentificationManager
{
   public AuthentificationManager(IEnumerable<IAuthentificationProvider> providers)
   {
      //do something with providers
   }

   //other class logic
}

现在,我只想注册已启用的提供程序。我尝试过类似的东西:

//finding all possible providers in assembly
var providerInterface = typeof(IAuthentificationProvider);
var types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(s => s.GetTypes())
    .Where(p => providerInterface.IsAssignableFrom(p) && !p.IsAbstract).ToList();

foreach (var type in types)
{
    //Register type as self for simple resolve in lambda expression
    containerBuilder.RegisterType(type).AsSelf().SingleInstance();
    containerBuilder.Register(c =>
    {
        var configs = c.Resolve<IAuthentificationProvidersConfig>();
        //get specific configuration for provider
        var config = configs.GetConfig(type.Name);
        if (config.IsEnabled)
        {
           //return provider
           return c.Resolve(type);
        }
        else
        {
           //"cancel the register"
           return new object();
        }

     }).As<IAuthentificationProvider>().SingleInstance();
}

在Autofac 4.9中,上面的代码有效,但是现在在Autofac 5.1.2中,行return new object();不再起作用:

InvalidCastException: Object cannot be stored in an array of this type.

我还有另一种取消lambda内寄存器的方法吗?

c# dependency-injection autofac
1个回答
0
投票

您无法在同一注册的lambda中取消注册。在我看来,您有两个选择:

1:拆分读取配置并配置容器

您应该更喜欢在应用程序启动时分割阶段,在此阶段您从注册容器的阶段读取配置。这使您可以根据配置值有条件地进行注册。

例如:

var configs = new AuthentificationProvidersConfig();

builder.RegisterInstance(configs).As<IAuthentificationProvidersConfig>();

foreach (var type in types)
{
    if (configs.GetConfig(type.Name).IsEnabled)
    {
        builder.Register(type).As<IAuthentificationProvider>().AsSingleInstance();
    }
}

2。创建一个允许在运行时过滤提供程序的组合]

如果第一个解决方案不可行,则可以在运行时过滤这些类型。这可以在AuthentificationManager内部执行,也可以在Composite IAuthentificationProvider实现内部进行。

© www.soinside.com 2019 - 2024. All rights reserved.