简体   繁体   中英

Autofac Cannot resolve parameter serviceScopeFactory of constructor 'Void

I get the following error when I try to inject IServiceScopeFactory in a class in my business layer: "Cannot resolve parameter 'Microsoft.Extensions.DependencyInjection.IServiceScopeFactory serviceScopeFactory' of constructor 'Void"

I havent worked with AutoFac before so I am wondering what I am missing:

This is my code:

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;
    }
}

where I try to inject the IServiceScopeFactory

public class PaymentHandler : IPaymentHandler
         {
            private readonly IServiceScopeFactory _serviceScopeFactory;

            public PaymentHandler(IServiceScopeFactory serviceScopeFactory)
            {
        
               _serviceScopeFactory = serviceScopeFactory;

            }
         }

         

It appears you're trying to kind of mix-and-match .NET 4.5 dependency injection (eg, with the DependencyResolver mechanism in Web API) and new .NET Core dependency injection (eg, IServiceProvider ). The really short answer here is... you can't do that.

If you read the exception it tells you exactly what's missing:

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

You have a constructor that takes an IServiceScopeFactory . You want Autofac to inject it. You didn't tell Autofac where to get it . No magic here: if you didn't register it with Autofac, Autofac's not going to be able to figure it out.

I'd guess what you want is the ability to create lifetime scopes inside that PaymentHandler . Since that's not really a thing in Web API with DependencyResolver , instead of trying to mix-and-match, you have to use Autofac directly.

Inject the ILifetimeScope instead.

public class PaymentHandler : IPaymentHandler
{
  private readonly ILifetimeScope _scope;

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

At this point, it'd be good to head over to the Autofac docs to learn more about lifetime scopes and how to work with them. But this should get you unblocked.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM