简体   繁体   中英

ServiceLocator with Autofac in asp.net core 3.1

I'm developing an asp.net core 3.1 webapi application and i'm using Autofac as DI container. For one particular case i cannot use ConstructorInjection nor propertyinjection nor methodinjection. My only way is to implement a sort of ServiceLocator pattern with the support of Autofac.

*I known that the service locator is an antipattern, but i will use that only if it will be the only chance *

Said that, I create a little static class :

public static class ServiceLocator
{

    private static XXXX Resolver;

    public static T Resolve<T>()
    {
        return Resolver.Resolve<T>();
    }

    public static void SetCurrentResolver(XXXX resolver)
    {
        Resolver = resolver;
    }
}

I write XXXX on the type of Resolver property because i don't know which is the Autofac class to use. The method SetCurrentResolver will be called in the Configure method of Startup.cs

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILifetimeScope serviceProvider)
    {
        //OTHER STUFF NOT RELATED HERE

        ServiceLocator.SetCurrentResolver(serviceProvider);
    }

I tried to pass the instance of ILifetimeScope but when i use it later in the service locator it will be Disposed and then not work. I thinked to pass an IContainer object but i'm not able to retrieve an instance in Startup.cs (neither in the Configure method nor in the ConfigureContainer )

I Report the ConfigureContainer method for completion

    public void ConfigureContainer(ContainerBuilder builder)
    {
        //first register the dependency for WebApi Project

        builder.RegisterType<HttpContextUserService>().As<IUserService>().SingleInstance();

        //and then register the dependency for all other project

        var appConfiguration = new AppConfiguration();
        Configuration.GetSection("Application").Bind(appConfiguration);
        builder.RegisterInstance(appConfiguration).SingleInstance();

        builder.RegisterModule(new DependencyInjectionBootstrapper(appConfiguration)); 
        
    }

Anyone can help me with this problem?

Thanks

This is actually answered in the Autofac docs if you look at the example.

Here are the relevant bits.

public class Startup
{
  public Startup(IHostingEnvironment env)
  {
    // Body omitted for brevity.
  }

  public ILifetimeScope AutofacContainer { get; private set; }

  public void ConfigureServices(IServiceCollection services)
  {
    // Body omitted for brevity.
  }

  public void ConfigureContainer(ContainerBuilder builder)
  {
    // Body omitted for brevity.
  }

  public void Configure(IApplicationBuilder app)
  {
    // If, for some reason, you need a reference to the built container, you
    // can use the convenience extension method GetAutofacRoot.
    // THIS IS WHERE YOU'D SET YOUR SERVICE LOCATOR.
    this.AutofacContainer = app.ApplicationServices.GetAutofacRoot();
  }
}

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