简体   繁体   English

注册模块 Autofac

[英]Registering Modules Autofac

I am using .NetCore 2.1 with autofaq in an asp.net core web application, my problem is the load method of my service module is not firing, I am instantiating a new instance of it as a parameter to registermodule, and the constructor of my service module is firing, this is a pretty typical setup, is there something i am doing wrong that anyone here can see?我在 asp.net core web 应用程序中使用带有 autofaq 的 .NetCore 2.1,我的问题是我的服务模块的加载方法没有触发,我正在实例化它的一个新实例作为 registermodule 的参数,以及我的构造函数服务模块正在触发,这是一个非常典型的设置,这里的任何人都可以看到我做错了什么吗?

ServiceModule.cs服务模块.cs

namespace MyApp.Managers.DependencyManagement
{
    public class ServiceModule : Module
    {
        public ServiceModule()
        {
            Console.WriteLine("YES THIS LINE OF CODE IS FIRING?");
        }

        protected override void Load(ContainerBuilder builder)
        {
            Console.WriteLine("Why am i not firing? :-( ");
            builder.RegisterType<ItemManager>().As<IItemManager>().InstancePerLifetimeScope();
        }
    }
}

Program.cs (pretty basic void main here) Program.cs(这里非常基本的 void main)

namespace MyApi.Api
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseKestrel()
                .ConfigureServices(services => services.AddAutofac())
                .ConfigureAppConfiguration((context, options) =>
                {
                    options.SetBasePath(Directory.GetCurrentDirectory())
                    .AddCommandLine(args);
                })
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseIISIntegration()
                .UseStartup<Startup>()
                .Build();

            host.Run();
        }
    }
}

Startup.cs (lots of stuff going on here) Startup.cs(这里有很多东西)

namespace MyApi.Api
{
    public class Startup
    {
        private readonly IHostingEnvironment env;
        private readonly IConfiguration config;
        private readonly ILoggerFactory loggerFactory;

        public Startup(
            IHostingEnvironment env,
            IConfiguration config,
            ILoggerFactory loggerFactory)
        {
            this.env = env;
            this.config = config;
            this.loggerFactory = loggerFactory;

            var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", EnvironmentVariableTarget.Machine);
            var appParentDirectory = new DirectoryInfo(this.env.ContentRootPath).Parent.FullName;

            var environmentName = environment ?? "Dev";
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{environmentName}.json", optional: false, reloadOnChange: true)
                .AddEnvironmentVariables();
            this.Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; private set; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info { Title = "Item Service", Version = "v1" });
                c.DescribeAllEnumsAsStrings();
            });

            services
                .AddMvc()
                .SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_1)
                .AddFluentValidation(x => x.RegisterValidatorsFromAssembly(Assembly.GetExecutingAssembly()));

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

        public void ConfigureContainer(ContainerBuilder builder)
        {
            var connectionString = this.Configuration.GetConnectionString("GildedRose");
            ServiceConfiguration.Register(this.AddWebServices, connectionString);
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseHttpsRedirection();

            app.UseSwagger();

            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
            });

            app.UseMvc();
        }

        private void AddWebServices(ContainerBuilder builder)
        {
        }
    }
}

ServiceConfiguration.cs (the constructor is firing, but the load method never fires) ServiceConfiguration.cs(构造函数正在触发,但 load 方法从不触发)

namespace MyApi.Api
{
    public class ServiceConfiguration
    {
        public static ContainerBuilder Register(Action<ContainerBuilder> additionalRegistration, string connectionString)
        {
            var containerBuilder = new ContainerBuilder();
            containerBuilder.RegisterType<ConfigurationStore>().As<IConfigurationStore>().InstancePerLifetimeScope();
            containerBuilder.RegisterType<Context>().AsSelf().InstancePerLifetimeScope();
            containerBuilder.RegisterModule(new StoreModule()
            {
                ConnectionString = connectionString,
            });
            containerBuilder.RegisterModule(new Managers.DependencyManagement.ServiceModule());
            additionalRegistration(containerBuilder);

            return containerBuilder;
        }
    }
}

You are not using the ContainerBuilder passed to the ConfigureContainer() method, instead you are instantiating and using a new one in the ServiceConfiguration.Register() , but that is not the one wired in the ASP.NET Core framework and also won't be built by it.您没有使用传递给ConfigureContainer()方法的ContainerBuilder ,而是在ServiceConfiguration.Register()中实例化并使用一个新方法,但这不是在 ASP.NET Core 框架中连接的,也不会由它建造。 That is why the Load() is not firing, you should use the one which is used by the framework.这就是Load()没有触发的原因,您应该使用框架使用的那个。

Try to pass it to your static method like this:尝试将其传递给您的静态方法,如下所示:

ServiceConfiguration.Register(this.AddWebServices, connectionString, builder);

And use it in your method like:并在您的方法中使用它,例如:

public static ContainerBuilder Register(Action<ContainerBuilder> additionalRegistration, 
string connectionString, 
ContainerBuilder containerBuilder)
{
    containerBuilder.RegisterType<ConfigurationStore>()
    .As<IConfigurationStore>()
    .InstancePerLifetimeScope();
    // the rest
}

With autofac you've got a couple ways of starting a service on creation:使用 autofac,您可以通过多种方式在创建时启动服务

Implementing IStartable on your service and adding a Start() method在您的服务上实现IStartable并添加一个Start()方法

or something like this:或类似的东西:

var builder = new ContainerBuilder();
builder.RegisterBuildCallback(c => c.Resolve<DbContext>());

// The callback will run after the container is built
// but before it's returned.
var container = builder.Build();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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