3

У меня возникли проблемы с AutoFac и IoC. Однако у нас есть рабочее приложение, я начинаю с нуля с этого и не вижу, где различия между ними.Проблема AutoFac DbContext - не может использоваться во время создания модели

Я тестирую это с помощью простой страницы AJAX, которая вызывает уровень сервиса через API ServiceStack. При использовании MockRepositories это работает отлично, поэтому я знаю, что эта сторона работает.

Однако, когда я заменяю mocks теми, которые используют 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 и охватываю несколько контекстов.

Может ли кто-нибудь определить место, где я ошибаюсь?

+0

Я столкнулся с той же проблемой. Вы нашли выход? – bhuvin

ответ

0

Строка подключения - проблема. Убедитесь, что вы правильно настроили его в своем веб-сайте/app.comfig.

Смежные вопросы