3

AutoFac と IoC を使い始める際にいくつか問題があります。動作するアプリケーションがありますが、私はこれをゼロから始めており、2 つの違いがどこにあるのかわかりません。

ServiceStack APIを介してサービスレイヤーを呼び出す単純なAJAXページでこれをテストしています。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 を間違って登録していて、複数のコンテキストにまたがっていることを示唆しています。

誰かが私が間違っている場所を見つけることができますか?

4

1 に答える 1

0

接続文字列が問題です。web/app.comfig で正しく設定されていることを確認してください。

于 2013-05-29T21:22:09.083 に答える