如何使用StructureMap注册表在单独的项目中配置EF Core?

时间:2017-10-27 15:43:56

标签: asp.net-core entity-framework-core structuremap

我试图在Visual Studio中设置一个解决方案,该解决方案在一个项目(Infrastructure)中包含所有EF Core文件,与我的ASP.NET Core Web项目分开。此外,我想阻止开发人员意外地使用基础结构项目中的类型,因此我试图避免从Web到基础结构的引用。这可以在ASP.NET 5 / EF 6中轻松完成,如下所述: https://ardalis.com/avoid-referencing-infrastructure-in-visual-studio-solutions

但是,在ASP.NET Core中,我们在Web项目的Startup.ConfigureServices()方法中配置EF Core:

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        string dbName = Guid.NewGuid().ToString();
        services.AddDbContext<AppDbContext>(options =>
            options.UseInMemoryDatabase(dbName));

        services.AddMvc()
            .AddControllersAsServices();

        // use StructureMap
        var container = new Container();
        container.Configure(config =>
        {
            config.Scan(_ =>
            {
                _.AssembliesAndExecutablesFromApplicationBaseDirectory();
                _.WithDefaultConventions();
                _.LookForRegistries();
            });

            config.Populate(services);
        });

        return container.GetInstance<IServiceProvider>();
    }

有没有办法将AddDbContext逻辑移出Startup并进入我的基础设施项目?我已经在Infrastructure项目中有一个StructureMap注册表,所以如果有一种方法可以从那里连接所需的服务,它就可以访问DbContext类型,因为它在该项目中:

public class InfrastructureRegistry : Registry
{
    public InfrastructureRegistry()
    {
        For(typeof(IRepository<>)).Add(typeof(EfRepository<>));
    }
}

您可以在此分支中查看项目的当前状态: https://github.com/ardalis/cleanarchitecture/tree/ardalis/projectref

我的目标是将项目引用从Web移除到基础结构,但仍然有解决方案在启动时加载AppDbContext。

1 个答案:

答案 0 :(得分:1)

您是否尝试手动添加到Registry DbContextBuilder:

示例:

public class InfrastructureRegistry : Registry
    {
        public InfrastructureRegistry()
        {
            string dbName = Guid.NewGuid().ToString();
            var option = new DbContextOptionsBuilder();
            var dbContextOptions = option.UseInMemoryDatabase(dbName).Options;
            For<AppDbContext>().Use(t => new AppDbContext(dbContextOptions, t.GetInstance<IDomainEventDispatcher>()));
            For(typeof(IRepository<>)).Add(typeof(EfRepository<>));
        }
    }

没有对此进行测试,但我认为如果您检查AddDbContext的作用(它使用的范围以及添加到dbContextOptions的配置),您可以手动将其注册到structuremap。