How to use StructureMap Registry to Configure EF Core in Separate Project?
Asked Answered
L

1

7

I'm trying to set up a solution in Visual Studio that has all of the EF Core files in one project (Infrastructure), separate from my ASP.NET Core web project. Further, I want to prevent developers from accidentally using types from the Infrastructure project, so I'm attempting to avoid having a reference from Web to Infrastructure. This is easily done in ASP.NET 5 / EF 6 as described here: https://ardalis.com/avoid-referencing-infrastructure-in-visual-studio-solutions

In ASP.NET Core, however, we configure EF Core in the web project's Startup.ConfigureServices() method:

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

Is there a way to move the AddDbContext logic out of Startup and into my Infrastructure project? I have a StructureMap registry in the Infrastructure project already, so if there's a way to wire up the required services from there, it will have access to the DbContext type since it's in that project:

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

You can view the current state of the project in this branch: https://github.com/ardalis/cleanarchitecture/tree/ardalis/projectref

My goal is to remove the project reference from Web to Infrastructure but still have the solution load the AppDbContext when it starts up.

Laryngoscope answered 27/10, 2017 at 15:43 Comment(1)
Could you please post your solution if you found one?Merrill
E
1

Did you try to add to Registry DbContextBuilder manually something like this:

example:

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

did not test this but I think if you check what AddDbContext does (what scope it use and what configurations are added to dbContextOptions)you can register that manually to structuremap.

Eighty answered 31/10, 2017 at 14:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.