【问题标题】:Autofac ResolvedParameter/ComponentContext not workingAutofac ResolvedParameter/ComponentContext 不起作用
【发布时间】:2020-08-23 21:55:39
【问题描述】:

我正在使用asp.net coreEntity Framework Core。我的场景是,我想在运行时根据HttpContext查询字符串值更改连接字符串。

我正在尝试将ResolvedParameterReflection components 作为documented 传递。但是,当我解决这个问题时,它没有被注册。下面,我附上了我的代码 sn-p。

Autofac 注册类:

public class DependencyRegistrar : IDependencyRegistrar
{
    public virtual void Register(ContainerBuilder builder)
    {
        builder.RegisterType(typeof(DbContextOptionsFactory))
            .As(typeof(IDbContextOptionsFactory))
            .InstancePerRequest();

        builder.RegisterType<AppDbContext>()
            .As(typeof(IDbContext))
            .WithParameter(
                new ResolvedParameter(
                    (pi, cc) => pi.Name == "options",
                    (pi, cc) => cc.Resolve<IDbContextOptionsFactory>().Get()));

        builder.RegisterGeneric(typeof(Repository<>))
            .As(typeof(IRepository<>))
            .SingleInstance();
    }
}

public interface IDbContextOptionsFactory
{
    DbContextOptions<AppDbContext> Get();
}

public class DbContextOptionsFactory : IDbContextOptionsFactory
{
    public DbContextOptions<AppDbContext> Get()
    {
        try
        {
            IConfigurationRoot configuration = new ConfigurationBuilder()
                                            .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
                                            .AddJsonFile("appsettings.json")
                                            .Build();

            var builder = new DbContextOptionsBuilder<AppDbContext>();

            if (EngineContext.Current.Resolve<IHttpContextAccessor>().HttpContext.Request.QueryString.ToString().ToLower().Contains("app1"))
                DbContextConfigurer.Configure(builder, configuration.GetConnectionString("app1"));
            else if (EngineContext.Current.Resolve<IHttpContextAccessor>().HttpContext.Request.QueryString.ToString().ToLower().Contains("app2"))
                DbContextConfigurer.Configure(builder, configuration.GetConnectionString("app2"));

            return builder.Options;
        }
        catch (Exception)
        {
            throw;
        }
    }
}

public class DbContextConfigurer
{
    public static void Configure(DbContextOptionsBuilder<AppDbContext> builder, string connectionString)
    {
        builder.UseSqlServer(connectionString);
    }
}

AppDbContext:

public class AppDbContext : DbContext, IDbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options)
        : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        Assembly assemblyWithConfigurations = typeof(IDbContext).Assembly;
        builder.ApplyConfigurationsFromAssembly(assemblyWithConfigurations);
    }

    //..
    //..
}

在运行时,我遇到错误。

处理请求时发生未处理的异常。

DependencyResolutionException:找不到任何构造函数 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' 类型 'AppDbContext' 可以用可用的调用 服务和参数:无法解析参数 'Microsoft.EntityFrameworkCore.DbContextOptions1[AppDbContext] options' of constructor 'Void .ctor(Microsoft.EntityFrameworkCore.DbContextOptions1[AppDbContext])'。 Autofac.Core.Activators.Reflection.ReflectionActivator.GetValidConstructorBindings(ConstructorInfo[] 可用的构造函数,IComponentContext 上下文, IEnumerable参数)

我试过answered here..但是,不行。

【问题讨论】:

  • 您是否尝试过仅注册选项? builder.Register(c =&gt; c.Resolve&lt;IDbContextOptionsFactory&gt;().Get()); ?
  • @GuruStron 当我将您的代码添加到builder.RegisterType&lt;AppDbContext&gt;()... 上方时,我收到了这个错误。 InvalidOperationException: No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions&lt;TContext&gt; object in its constructor and passes it to the base constructor for DbContext.
  • @GuruStron 谢谢! :) 它对代码的修改很少。我已将其发布为答案。根据您的评论和我的理解,builder.Register() 在将委托注册为组件时使用。如果这样做,AutofacComponentContext 中解析该委托。对吗?

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


【解决方案1】:

我已通过按照 Guru Stron 的评论和后续更改进行更改来解决此问题。这是我的零钱。

第 1 步: 将 Autofac 注册类更改如下:

public class DependencyRegistrar : IDependencyRegistrar
{
    public virtual void Register(ContainerBuilder builder)
    {
        //Removed this code
        //builder.RegisterType(typeof(DbContextOptionsFactory))
        //    .As(typeof(IDbContextOptionsFactory))
        //    .InstancePerRequest();

        //Added this code
        builder.Register(c => c.Resolve<IDbContextOptionsFactory>().Get())
            .InstancePerDependency();  // <-- Changed this line

        builder.RegisterType<AppDbContext>()
            .As(typeof(IDbContext))
            .WithParameter(
                new ResolvedParameter(
                    (pi, cc) => pi.Name == "options",
                    (pi, cc) => cc.Resolve<IDbContextOptionsFactory>().Get()))
            .InstancePerDependency();  // <-- Added this line

        builder.RegisterGeneric(typeof(Repository<>))
            .As(typeof(IRepository<>))
            .InstancePerDependency();  // <-- Changed this line
    }
}

现在,如果您收到错误消息:

InvalidOperationException:未配置数据库提供程序 对于这个 DbContext。可以通过覆盖来配置提供程序 DbContext.OnConfiguring 方法或通过在上使用 AddDbContext 应用服务提供商。如果使用了 AddDbContext,那么也 确保您的 DbContext 类型接受 DbContextOptions 构造函数中的对象并将其传递给基构造函数 数据库上下文。

通过在AppDbContext 类中添加以下代码来解决上述错误。

第二步:修改AppDbContext(添加OnConfiguring()方法)

public class AppDbContext : DbContext, IDbContext
{
    public AppDbContext(DbContextOptions<AppDbContext> options)
        : base(options)
    {

    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        Assembly assemblyWithConfigurations = typeof(IDbContext).Assembly;
        builder.ApplyConfigurationsFromAssembly(assemblyWithConfigurations);
    }

    //Added this method
    protected override void OnConfiguring(DbContextOptionsBuilder dbContextOptionsBuilder)
    {
        base.OnConfiguring(dbContextOptionsBuilder);
    }

    //..
    //..
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-09
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    相关资源
    最近更新 更多