Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 974
ssmith Avatar asked Oct 27 '17 15:10

ssmith


1 Answers

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.

like image 198
Florim Maxhuni Avatar answered Sep 25 '22 02:09

Florim Maxhuni