Autofac 无法解析构造函数“Void”的参数 serviceScopeFactory

Autofac Cannot resolve parameter serviceScopeFactory of constructor 'Void

当我尝试在业务层的 class 中注入 IServiceScopeFactory 时出现以下错误:“无法解析构造函数‘Void’的参数 'Microsoft.Extensions.DependencyInjection.IServiceScopeFactory serviceScopeFactory'”

我之前没有使用过 AutoFac,所以我想知道我错过了什么:

这是我的代码:

private static void ConfigureAutoFacIoC(ContainerBuilder builder, HttpConfiguration config, IAppBuilder app)
    {
        AutoFacRegister.RegisterDependency(builder, Assembly.GetExecutingAssembly());
        RegisterWebApiDependency(builder);

        builder.RegisterWebApiFilterProvider(config);
        var container = builder.Build();
        // Set the dependency resolver to be Autofac.
        config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
        app.UseAutofacMiddleware(container);
        app.UseAutofacWebApi(config);
    }

public static class AutoFacRegister
{
    public static void RegisterDependency(ContainerBuilder builder, Assembly webApiAssembly)
    {
        RegisterDataLayer(builder);
        RegisterBusinessLayer(builder);
        RegisterShared(builder);
        RegisterPresentationLayer(builder, webApiAssembly);
    }

    private static void RegisterDataLayer(ContainerBuilder builder)
    {
        builder.RegisterType<SBSContext>().InstancePerLifetimeScope();
        builder.RegisterType<AgdaContext>().InstancePerLifetimeScope();
        builder.RegisterType<MailingRepository>().As<IMailingRepository>();
        builder.RegisterType<MembershipRepository>().As<IMembershipRepository>();
        builder.RegisterType<CourseMomentRepository>().As<ICourseMomentRepository>();
        builder.RegisterType<MedalRepository>().As<IMedalRepository>();
        builder.RegisterType<PersonRepository>().As<IPersonRepository>();
        builder.RegisterType<CourseRepository>().As<ICourseRepository>();
        builder.RegisterType<OrganisationRepository>().As<IOrganisationRepository>();
        builder.RegisterType<FunctionRepository>().As<IFunctionRepository>();
        builder.RegisterType<PaymentRepository>().As<IPaymentRepository>();
        builder.RegisterType<ChargeCategoryRepository>().As<IChargeCategoryRepository>();
        builder.RegisterType<OutcodeRepository>().As<IOutcodeRepository>();
        builder.RegisterType<UserRepository>().As<IUserRepository>();
        builder.RegisterType<ViewPersonRepository>().As<IViewPersonRepository>();
        builder.RegisterType<AgdaRepository>().As<IAgdaRepository>();
        builder.RegisterType<ReportRepository>().As<IReportRepository>();
        builder.RegisterType<ReportManager>().As<IReportManager>();
        builder.RegisterType<CourseApplicationRepository>().As<ICourseApplicationRepository>();
        builder.RegisterType<RepdayRepository>().As<IRepdayRepository>();
        builder.RegisterType<ChargeCategoryRepository>().As<IChargeCategoryRepository>();
        builder.RegisterType<CommuneRepository>().As<ICommuneRepository>();
        builder.RegisterType<PapApiAmbassador>().As<IPapApiAmbassador>();
        builder.RegisterType<VolenteerRepository>().As<IVolenteerRepository>();
        builder.RegisterType<AgreementTypeRepository>().As<IAgreementTypeRepository>();
        builder.RegisterType<CourseMomentStatusRepository>().As<ICourseMomentStatusRepository>();
        builder.RegisterType<CourseTypeRepository>().As<ICourseTypeRepository>();
        builder.RegisterType<AttestationRepository>().As<IAttestationRepository>();

        builder.RegisterGeneric(typeof(GenericRepository<,>)).As(typeof(IGenericRepository<,>));

    }

    private static void RegisterBusinessLayer(ContainerBuilder builder)
    {
        var bllAssembly = AppDomain.CurrentDomain.GetAssemblies().
            SingleOrDefault(assembly => assembly.GetName().Name == "SBS.Ferdinand.BusinessLayer");

        builder.RegisterAssemblyTypes(typeof(IServiceScopeFactory).Assembly).As<IServiceScopeFactory>();

        builder.RegisterAssemblyTypes(bllAssembly)
            .Where(x => x.Name.EndsWith("Handler"))
            .AsImplementedInterfaces();

        builder.RegisterAssemblyTypes(bllAssembly)
            .Where(x => x.Name.EndsWith("Helper"))
            .AsImplementedInterfaces()
            .SingleInstance();

        builder.RegisterType<OrganisationMigrator>().As<IOrganisationMigrator>();
    }
    private static void RegisterShared(ContainerBuilder builder)
    {
        builder.RegisterType<BaseRequestModel>().AsImplementedInterfaces().InstancePerLifetimeScope();
        builder.RegisterType<ImpersonateUser>().As<IImpersonateUser>();
        builder.RegisterModule<NLogModule>();
        builder.RegisterType<ApiApplicationSettings>().As<IApiApplicationSettings>().SingleInstance();
    }

    private static void RegisterPresentationLayer(ContainerBuilder builder, Assembly webApiAssembly)
    {
        builder.RegisterApiControllers(webApiAssembly);
    }

    public static void RegisterHangfireDependency(ContainerBuilder builder)
    {
        RegisterDataLayer(builder);
        RegisterBusinessLayer(builder);
        RegisterShared(builder);
        builder.RegisterType<CronJobManager>().As<ICronJobManager>().InstancePerLifetimeScope();
    }
}
public class NLogModule : Autofac.Module
{
    private static void OnComponentPreparing(object sender, PreparingEventArgs e)
    {
        e.Parameters = e.Parameters.Union(
            new[]
            {
                new ResolvedParameter(
                    (p, i) => p.ParameterType == typeof (ILogger),
                    (p, i) => LogManager.GetLogger(p.Member.DeclaringType.FullName))
            });
    }

    protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
    {
        // Handle constructor parameters.
        registration.Preparing += OnComponentPreparing;
    }
}

我尝试在其中注入 IServiceScopeFactory

public class PaymentHandler : IPaymentHandler
         {
            private readonly IServiceScopeFactory _serviceScopeFactory;

            public PaymentHandler(IServiceScopeFactory serviceScopeFactory)
            {
        
               _serviceScopeFactory = serviceScopeFactory;

            }
         }

         

看来您正在尝试 mix-and-match .NET 4.5 依赖注入(例如,使用 Web API 中的 DependencyResolver 机制)和新的 .NET Core 依赖注入(例如,IServiceProvider)。这里真正简短的回答是......你不能那样做。

如果您阅读异常,它会准确告诉您缺少什么:

Cannot resolve parameter 'Microsoft.Extensions.DependencyInjection.IServiceScopeFactory'

您有一个采用 IServiceScopeFactory 的构造函数。你想让 Autofac 注入它。您没有告诉 Autofac 从哪里得到它。这里没有魔法:如果你没有在 Autofac 上注册它,Autofac 将无法解决这个问题。

我猜你想要的是在 PaymentHandler 中创建生命周期范围的能力。因为这在 Web API 和 DependencyResolver 中不是真正的事情,而不是尝试 mix-and-match,你必须直接使用 Autofac。

改为注入 ILifetimeScope

public class PaymentHandler : IPaymentHandler
{
  private readonly ILifetimeScope _scope;

  public PaymentHandler(ILifetimeScope scope)
  {
    _scope = scope;
    // now you can do
    // using(var childScope = _scope.BeginLifetimeScope){ }
  }
}

此时,it'd be good to head over to the Autofac docs 了解有关生命周期作用域以及如何使用它们的更多信息。但这应该能让你畅通无阻。