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

C# 基于条件的Autofac 5中止寄存器,c#,dependency-injection,autofac,C#,Dependency Injection,Autofac,对于应用程序,我有多个IAuthenticationProvider: public interface IAuthentificationProvider { bool IsUserValid(string login, string password) } 对于每个IAuthentificationProvider,我都有一个与以下内容关联的IAuthentificationProviderConfig: public interface IAuthentificationProvi

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

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
}

是否有其他方法可以取消lambda内部的注册?

您不能取消同一注册的lambda内部的注册。在我看来,你有两个选择:

1:拆分读取容器的配置和配置 您应该更喜欢在应用程序启动阶段(从注册容器的阶段读取配置)中拆分阶段。这允许您根据配置值有条件地进行注册

例如:

var configs=new authenticationProvidersConfig();
builder.RegisterInstance(configs).As();
foreach(类型中的变量类型)
{
if(configs.GetConfig(type.Name).IsEnabled)
{
builder.Register(type).As().AsSingleInstance();
}
}
2.创建允许在运行时筛选提供程序的组合 如果第一个解决方案不可行,您可以在运行时过滤这些类型。有多种方法可以做到这一点,例如将
IEnumerable
隐藏在组合后面,或者过滤
AuthentificationManager
中的类型,或者可能只是直接使用lambda注册
IEnumerable
,以便构建过滤列表:

foreach (var type in types)
{
    //Register type as self for simple resolve in lambda expression
    containerBuilder.RegisterType(type)
        .AsSelf()
        .SingleInstance();
}

containerBuilder.Register(c => (
    from type in types
    let configs = c.Resolve<IAuthentificationProvidersConfig>()
    let config = configs.GetConfig(type.Name)
    where config.IsEnabled
    select (IAuthentificationProvider)c.Resolve(type))
    .ToList()
    .AsReadOnly())
    .As<IEnumerable<IAuthentificationProvider>>()
    .SingleInstance();

foreach(类型中的变量类型)
{
//将类型注册为self,以便在lambda表达式中进行简单解析
containerBuilder.RegisterType(类型)
.AsSelf()
.SingleInstance();
}
containerBuilder.Register(c=>(
从输入类型
让configs=c.Resolve()
让config=configs.GetConfig(type.Name)
其中config.IsEnabled
选择(IAuthenticationProvider)c.Resolve(类型))
托利斯先生()
.AsReadOnly())
.As()
.SingleInstance();
InvalidCastException: Object cannot be stored in an array of this type.
foreach (var type in types)
{
    //Register type as self for simple resolve in lambda expression
    containerBuilder.RegisterType(type)
        .AsSelf()
        .SingleInstance();
}

containerBuilder.Register(c => (
    from type in types
    let configs = c.Resolve<IAuthentificationProvidersConfig>()
    let config = configs.GetConfig(type.Name)
    where config.IsEnabled
    select (IAuthentificationProvider)c.Resolve(type))
    .ToList()
    .AsReadOnly())
    .As<IEnumerable<IAuthentificationProvider>>()
    .SingleInstance();