Create database context from cookie and base path in Entity Framework Core

流过昼夜 提交于 2021-01-29 11:16:54

问题


Postgres database has multiple schemes like company1, company2, ... companyN

Browser sends cookie containing scheme name . Data access operations should occur in this scheme. Web application user can select different scheme. In this case different cookie value is set.

Npgsql EF Core Data provider is used.

ASP NET MVC 5 Core application registers factory in StartUp.cs :

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpContextAccessor();
        services.AddScoped<IEevaContextFactory, EevaContextFactory>();
      ....

Home controller tries to use it:

public class HomeController : EevaController
{
    public ActionResult Index()
    {
        var sm = new SchemeManager();
        sm.PerformInsert();
    ....

This throws exception since factory member is null. How to fix this ?

public interface IEevaContextFactory
{
    EevaContext Create();
}

public class EevaContextFactory : IEevaContextFactory
{
    private IHttpContextAccessor httpContextAccessor;
    private IConfiguration configuration;

    public EevaContextFactory(IHttpContextAccessor httpContextAccessor, IConfiguration configuration)
    {
        this.httpContextAccessor = httpContextAccessor;
        this.configuration = configuration;
    }

    public EevaContext Create()
    {
        var builder = new DbContextOptionsBuilder<EevaContext>();
        var pathbase = httpContextAccessor.HttpContext.Request.PathBase.Value;
        var scheme = httpContextAccessor.HttpContext.Request.Cookies["Scheme"];

        var csb = new NpgsqlConnectionStringBuilder()
        {
            Host = pathbase,
            SearchPath = scheme
        };
        builder.UseNpgsql(csb.ConnectionString);
        return new EevaContext(builder.Options);
    }
}

Scheme data acess methods:

public class SchemeManager
{
    readonly IEevaContextFactory factory;

    public SchemeManager(IEevaContextFactory factory)
    {
        this.factory = factory;
    }

    public SchemeManager()
    {
    }

    public void PerformInsert()
    {
        using (var context = factory.Create())
        {
            var commandText = "INSERT into maksetin(maksetin) VALUES (CategoryName)";
            context.Database.ExecuteSqlRaw(commandText);
        }
    }
}

回答1:


var sm = new SchemeManager()

... will call the no-parameter constructor on SchemeManager so the IEevaContextFactory is not injected. You should inject your factory into your controller and pass it into your SchemeManager.

Remove your no-parameter constructor. It's not needed.

public class HomeController : EevaController
{
    private IEevaContextFactor eevaFactory;
           
    public HomeController(IEevaContextFactory factory)
    {
         eevaFactory = factory;
    }
        
    public ActionResult Index()
    {
         var sm = new SchemeManager(eevaFactory);
         sm.PerformInsert();
         ....
    }
}

Your other option is to put the SchemeManager in the DI container and then the DI container will auto-resolve IEevaContextFactory on the constructor and then just inject SchemeManager into your controller.

Either way, remove that no-parameter constructor.



来源:https://stackoverflow.com/questions/65478936/create-database-context-from-cookie-and-base-path-in-entity-framework-core

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!