在AspNET Core中使用DI

时间:2019-01-16 22:21:59

标签: c# asp.net-core dependency-injection

我有一个DbContext派生类,称为NavigationContext,如下所示:

public class NavigationContext : DbContext
{
    private readonly IConfiguration _configuration;

    public NavigationContext(DbContextOptions<NavigationContext> options, IConfiguration configuration) : base(options)
    {
        _configuration = configuration;
    }
    //DbSets here ...

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder.UseSqlServer(_configuration.GetConnectionString("NavigationLoggingDatabase"));
        }
    }
}

将配置注册到Startup.cs的DI容器中,如下所示:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddDbContext<NavigationContext>(options => options.UseSqlServer(Configuration.GetConnectionString("NavigationLoggingDatabase")));
        services.AddSingleton(_ => Configuration);
    }

我的问题是我应该发送什么给NavigationContext构造函数?

    public int Add(TEntity item)
    {
        using (NavigationContext context = new NavigationContext(_contextOptionsBuilder.Options, ???))
        {
            context.Set<TEntity>().Add(item);
            context.SaveChanges();
            return item.Id;
        }
    }

2 个答案:

答案 0 :(得分:2)

那不是您执行DI(依赖注入)的方式。每当您看到服务的new关键字时,就必须知道它是错误的。

首先,您不必向DbContext传递任何内容,OnConfiguring覆盖不应该存在,因为您没有使用它。该调用负责该配置:

services.AddDbContext<NavigationContext>(options => options.UseSqlServer(Configuration.GetConnectionString("NavigationLoggingDatabase")));

第二,您不要将using用于注入的依赖项,因此:

public int Add(TEntity item)
{
    _context.Set<TEntity>().Add(item);
    _context.SaveChanges();
    return item.Id;
}

而且,为了起作用:

public class SomeController : Controller
{
    private readonly NavigationContext _context;

    public SomeController(NagivationContext context)
    {
        _context = context;
    }
}

并且,作为最后的建议,您应该确实尽可能地使用Entity Framework Core方法的异步版本:

public async Task<int> Add(TEntity item)
{
    _context.Set<TEntity>().Add(item);
    await _context.SaveChangesAsync();
    return item.Id;
}

答案 1 :(得分:2)

您根本不使用new NavigationContext(...),如果这样做,您将完全失去依赖注入的要点。相反,您应该将上下文注入到需要它的类中。例如,如果您直接在控制器中需要它,则看起来像这样:

public class FunkyController : Controller
{
    private readonly NavigationContext _nagivationContext;

    public FunkyController(NagivationContext nagivationContext)
    {
        //Context is injected into the constructor of the controller
        _nagivationContext = nagivationContext;
    }

    public int Add(TEntity item)
    {
        _nagivationContext.Set<TEntity>().Add(item);
        _nagivationContext.SaveChanges();
        return item.Id;
    }
}