Использование DI в AspNET Core - PullRequest
0 голосов
/ 17 января 2019

У меня есть производный класс 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"));
        }
    }
}

Конфигурация регистрируется в контейнере DI в Startup.cs, например:

    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 голосов
/ 17 января 2019

Вы вообще не используете 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;
    }
}
0 голосов
/ 17 января 2019

Это не так, как вы делаете DI (Dependency Injection). Всякий раз, когда вы видите ключевое слово 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;
}
...