簡體   English   中英

AutoFac DbContext問題 - 在模型創建時無法使用

[英]AutoFac DbContext issue - cannot be used while the model is creating

我在使用AutoFac和IoC時遇到了一些問題。 我們有一個有效的應用程序,但是我從頭開始使用這個應用程序並且無法看到兩者之間的差異。

我正在使用一個簡單的AJAX頁面測試它,該頁面通過ServiceStack API調用服務層。 當使用MockRepositories時,這很好用,所以我知道事情的一面是有效的。

但是當我用使用Entity Framework的模擬替換模擬時,盡管所有注冊看起來都是正確且有效的,但我得到錯誤“在創建模型時不能使用上下文”。

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

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並且它跨越多個上下文。

誰能發現我哪里出錯?

連接字符串是個問題。 確保您已在web / app.comfig中正確設置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM