注册模块Autofac

时间:2018-11-09 14:14:07

标签: c# asp.net asp.net-core dependency-injection autofac

我在asp.net核心Web应用程序中将.NetCore 2.1与autofaq一起使用,我的问题是服务模块的加载方法未触发,我将其新实例实例化为registermodule的参数,并且我的服务模块的构造函数正在触发,这是一个非常典型的设置,我在做错什么吗,这里的任何人都可以看到?

ServiceModule.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(此处是基本的void主功能)

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(很多事情在这里发生)

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(构造函数正在触发,但是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;
        }
    }
}

2 个答案:

答案 0 :(得分:2)

您没有使用传递给ContainerBuilder方法的ConfigureContainer(),而是实例化并在ServiceConfiguration.Register()中使用了一个新值,但这不是ASP中连接的那个.NET Core框架,也不会由此构建。这就是Load()不触发的原因,您应该使用框架使用的那个。

尝试像这样将其传递给您的静态方法:

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

并在您的方法中使用它,例如:

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

答案 1 :(得分:0)

使用autofac,您可以在创建过程中使用starting a service的几种方式:

在您的服务上实施IStartable并添加一个Start()方法

或类似的内容:

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();
相关问题