Autofac ResolvedParameter/ComponentContext不起作用 [英] Autofac ResolvedParameter/ComponentContext not working
问题描述
我正在将asp.net core
和Entity Framework Core
一起使用.我的情况是,我想在运行时根据HttpContext
查询字符串值更改连接字符串.
I am using asp.net core
along with Entity Framework Core
. My scenario here is, I want to change the connection string at runtime based on HttpContext
query string value.
我正在尝试将ResolvedParameter
和Reflection components
传递为已记录.但是,当我解决此问题时,它没有被注册.在下面,我附上了我的代码段.
I am trying to pass ResolvedParameter
with Reflection components
as documented. But, It is not getting registered when I resolve this. Here below, I have attached my code snippet.
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);
}
//..
//..
}
在运行时,我遇到了错误.
During runtime, I am getting below error.
处理请求时发生未处理的异常.
An unhandled exception occurred while processing the request.
DependencyResolutionException:找不到与之相关的构造函数
类型上的"Autofac.Core.Activators.Reflection.DefaultConstructorFinder"
可以使用"AppDbContext"调用
服务和参数:无法解析参数
'Microsoft.EntityFrameworkCore.DbContextOptions 1[AppDbContext]
options' of constructor 'Void
.ctor(Microsoft.EntityFrameworkCore.DbContextOptions
1 [AppDbContext])'.
Autofac.Core.Activators.Reflection.ReflectionActivator.GetValidConstructorBindings(ConstructorInfo []
availableConstructors,IComponentContext上下文,
IEnumerable参数)
DependencyResolutionException: None of the constructors found with
'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type
'AppDbContext' can be invoked with the available
services and parameters: Cannot resolve parameter
'Microsoft.EntityFrameworkCore.DbContextOptions1[AppDbContext]
options' of constructor 'Void
.ctor(Microsoft.EntityFrameworkCore.DbContextOptions
1[AppDbContext])'.
Autofac.Core.Activators.Reflection.ReflectionActivator.GetValidConstructorBindings(ConstructorInfo[]
availableConstructors, IComponentContext context,
IEnumerable parameters)
我已经尝试在此处回答 ..但无法正常工作.
I have tried as answered here..but, not working.
推荐答案
我已经解决了此问题,方法是作为Guru Stron的注释和后续更改进行更改.这是我的零钱.
I have resolved this issue by doing change as Guru Stron's comment and subsequent changes. Here is my change.
步骤1:更改了Autofac注册类别,如下所示:
Step 1: Changed Autofac Registration class as below:
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,则也 确保您的DbContext类型接受DbContextOptions 对象在其构造函数中并将其传递给基本构造函数 DbContext.
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 object in its constructor and passes it to the base constructor for DbContext.
通过在AppDbContext
类中添加以下代码来解决上述错误.
By add below code in AppDbContext
class to resolve above error.
步骤2:修改了AppDbContext
(添加了OnConfiguring()
方法)
Step 2: Modified AppDbContext
(Added OnConfiguring()
method)
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);
}
//..
//..
}
这篇关于Autofac ResolvedParameter/ComponentContext不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!