AutoFac DbContext 问题 - 在创建模型时无法使用

Posted

技术标签:

【中文标题】AutoFac DbContext 问题 - 在创建模型时无法使用【英文标题】:AutoFac DbContext issue - cannot be used while the model is creating 【发布时间】:2013-03-04 02:00:47 【问题描述】:

我在开始使用 AutoFac 和 IoC 时遇到了一些问题。我们有一个可用的应用程序,但是,我从头开始使用这个应用程序,看不出两者之间的区别在哪里。

我正在使用一个简单的 AJAX 页面对此进行测试,该页面通过 ServiceStack API 调用服务层。当使用 MockRepositories 时,它工作得很好,所以我知道事情的那一面是有效的。

但是,当我将模拟替换为使用实体框架的模拟时,尽管所有注册似乎都正确且有效,但我收到错误消息“在创建模型时无法使用上下文。”

我在下面包含了我的代码:

public class SomeObject

    public int Id  get; set; 




public class IoCExampleContext : DbContext, IIoCExampleContext


    public IDbSet<SomeObject> SomeObjects  get; set; 

    static IoCExampleContext()
    
        Database.SetInitializer(new IoCExampleDatabaseInitilizer());
    

    public IoCExampleContext(string connectionStringName)
        : base(connectionStringName)
    
        Configuration.ProxyCreationEnabled = false;
    

    public IoCExampleContext()
        : this("name=IoCExample")
    


    public string ConnectionString
    
        get  return Database.Connection.ConnectionString; 
    


    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    
        base.OnModelCreating(modelBuilder);
        BuildModels(modelBuilder);
    

    private void BuildModels(DbModelBuilder builder)
    
        var typeToUse = typeof(SomeObjectModelBuilder);
        var namespaceToUse = typeToUse.Namespace;

        var toReg = Assembly
                        .GetAssembly(typeToUse)
                        .GetTypes()
                        .Where(type => type.Namespace != null && type.Namespace.StartsWith(namespaceToUse))
                        .Where(type => type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));

        foreach (object configurationInstance in toReg.Select(Activator.CreateInstance))
        
            builder.Configurations.Add((dynamic)configurationInstance);
        
    




public class IoCExampleDatabaseInitilizer : CreateDatabaseIfNotExists<IoCExampleContext>

    protected override void Seed(IoCExampleContext context)
    
    




public interface IRepository<TEntity> where TEntity : class

    IQueryable<TEntity> GetQuery();
    IEnumerable<TEntity> GetAll();
    IEnumerable<TEntity> Where(Expression<Func<TEntity, bool>> predicate);

    // ...Various "standard" CRUD calls




public class GenericRepository<TEntity> : IRepository<TEntity> where TEntity : class

    protected DbContext _context;
    private readonly DbSet<TEntity> _dbSet;

    public GenericRepository(DbContext context)
    
        _context = context;
        _dbSet = _context.Set<TEntity>();
    

    public IQueryable<TEntity> GetQuery()
    
        return _dbSet;
    

    public IEnumerable<TEntity> GetAll()
    
        return GetQuery().AsEnumerable();
    

    public IEnumerable<TEntity> Where(Expression<Func<TEntity, bool>> predicate)
    
        return GetQuery().Where(predicate);
    

    // ...Various "standard" CRUD calls

    public void Dispose()
    
        OnDispose(true);
    

    protected void OnDispose(bool disposing)
    
        if (disposing)
        
            if (_context != null)
            
                _context.Dispose();
                _context = null;
            
        
    



public class DependencyBootstrapper

    private ContainerBuilder _builder;

    public IContainer Start()
    
        _builder = new ContainerBuilder();
        _builder.RegisterFilterProvider();
        RegisterControllers();
        return _builder.Build();
    

    private void RegisterControllers()
    
        RegisterAssembly(Assembly.GetExecutingAssembly());
        _builder.RegisterModelBinderProvider();

        RegisterPerLifetimeConnections();
        RegisterRepositories();
        RegisterServices();
    

    private void RegisterAssembly(Assembly assembly)
    
        _builder.RegisterModelBinders(assembly);
        _builder.RegisterControllers(assembly);
    

    private void RegisterRepositories()
    
        _builder.RegisterGeneric(typeof(GenericRepository<>)).As(typeof(IRepository<>)); 
        _builder.RegisterType<GenericRepository<SomeObject>>().As<IRepository<SomeObject>>();
        //... More registrations
    

    private void RegisterServices()
    
        _builder.RegisterType<SomeObjectService>().As<ISomeObjectService>();
        //... More registrations
    

    private void RegisterPerLifetimeConnections()
    
        const string connectionStringName = "IoCExample";
        _builder.RegisterType<IoCExampleContext>()
            .As<DbContext>()
            .WithParameter("connectionStringName", connectionStringName)
            .InstancePerLifetimeScope();

        _builder.Register(c => new HttpContextWrapper(HttpContext.Current))
            .As<HttpContextBase>();
    

我不知道这是否相关,但由于我们无法访问 global.asax 方法,我们通过 PreApplicationStartMethod.OnPreApplicationStart 调用引导程序(据我所知,这几乎是一回事作为 Application_Start)。

有点令人担忧的是,当我在连接字符串上启用多个活动结果集时,它可以工作 - 这表明我错误地注册了 DbContext 并且它跨越了多个上下文。

谁能发现我哪里出错了?

【问题讨论】:

我面临同样的问题。你找到出路了吗? 【参考方案1】:

连接字符串是问题所在。确保您已在 web/app.comfig 中正确设置。

【讨论】:

以上是关于AutoFac DbContext 问题 - 在创建模型时无法使用的主要内容,如果未能解决你的问题,请参考以下文章

AutoFac DbContext 问题 - 在创建模型时无法使用

autofac 多个dbcontext 上下文不一致

如何使用autofac实现多个DbContext的注入

从零开始搭建前后端分离的NetCore(EF Core CodeFirst+Au)+Vue的项目框架之二autofac解耦

AutoFac实现WebAPI依赖注入(EF以及Mysql)

一步一步学EF系列6IOC 之AutoFac