AutoFac DbContext问题——不能在模型创建时使用

本文关键字:创建 模型 DbContext 问题 不能 AutoFac | 更新日期: 2023-09-27 18:04:08

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

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

然而,当我用使用实体框架的模型替换mock时,虽然所有注册似乎都是正确的和工作的,但我得到错误"在创建模型时不能使用上下文"。

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

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>();
    }
}

我不知道这是否相关,但我们无法访问全局。我们通过PreApplicationStartMethod.OnPreApplicationStart调用bootstrapper的asax方法(据我所知,这与Application_Start几乎是一样的)。

有一点值得关注的是,当我在连接字符串上启用多个活动结果集时,它会工作-这表明我正在错误地注册DbContext,并且它跨越多个上下文。

有谁能指出我错在哪里吗?

AutoFac DbContext问题——不能在模型创建时使用

连接字符串是问题所在。确保你已经在web/app. config中正确设置了