Это не так, как вы делаете 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;
}
И, чтобы это работало: [ 1110]
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;
}
Необходимо проверить эту превосходную запись в блоге моего коллеги Calvin. У нас недавно была ситуация, где мы хотели включить этот тип фиксации, чтобы к утечкам ассоциативной памяти со строкой, которая выделила их в сборках диагностики/отладки. Это - интересный прием
http://blogs.msdn.com/calvin_hsia/archive/2009/01/19/9341632.aspx
3.7.4 продолжительностей Динамической памяти
2 библиотека предоставляет определения по умолчанию для глобальных функций выделения и освобождения. Некоторые глобальные функции выделения и освобождения заменимы (18.5.1). Программа C++ должна предоставить самое большее одно определение заменимой функции выделения или освобождения. Любое такое функциональное определение заменяет версию по умолчанию, обеспеченную в библиотеке (17.6.4.6) [...]
17.6.4.6 Заменяющих функции
, программа C++ А может предоставить определение для любой из восьми подписей функции динамического выделения памяти, объявленных в заголовке (3.7.4, Пункт 18):
- новый оператор (станд.:: size_t)
- новый оператор (станд.:: size_t, станд. константы:: nothrow_t&)
- оператор, новый [] (станд.:: size_t)
- оператор, новый [] (станд.:: size_t, станд. константы:: nothrow_t&)
- оператор удаляет (пусто*)
- , оператор удаляет (пусто*, станд. константы:: nothrow_t&)
- оператор удаляет [] (пусто*)
- , оператор удаляет [] (пусто*, станд. константы:: nothrow_t&)
Hope это разъясняет то, что является легальной перегрузкой и что не.
Это может представлять интерес для некоторых здесь:
#define delete cout << "delete called at: " << __LINE__ << " of " << __FILE__ << endl, delete
using namespace std;
void *operator new(size_t size, ostream& o, char *f, unsigned l) {
o << "new called at: " << l << " of " << f << endl;
return ::new char[size];
}
int main() {
int *a = new(cout, __FILE__, __LINE__) int;
delete a;
}
Чтец Протеста : Что я делаю вот Bad Thing (TM), чтобы сделать - перегрузка нового/удаляющего глобально.
Вы не говорите, какой компилятор Вы используете, но по крайней мере с GCC, можно переопределить новый и зарегистрировать адрес вызывающей стороны, тогда позже перевести это в информацию о файле/строке с addr2line (или пользоваться библиотекой BFD, чтобы сразу сделать это).
Я нашел следующую библиотеку" , nvwa", очень полезный для того, чтобы разыскать новые/удаленные утечки памяти - взглянул на файл "debug_new" для примеров или просто использует его как есть ''.
Нет, нет никакого пути.
Вы могли сделать это в плохие былые времена malloc()/free()
, но не для new
.
можно заменить средство выделения памяти путем глобального переопределения new
оператор, но Вы не можете ввести специальные переменные, о которых Вы говорите.
То, что Вы могли сделать, должно перегрузить новый оператор и получить отслеживание стека там (конкретная платформа) и использовать данные стека для выведения из, где новый был назван.
Вот что я использую:
В new.cpp
const char* __file__ = "unknown";
size_t __line__ = 0;
void* operator new(size_t size) {
void *ptr = malloc(size);
record_alloc(ptr,__file__,__line__);
__file__ = "unknown";
__line__ = 0;
return ptr;
}
void delete(void *ptr)
{
unrecord_alloc(ptr);
free(ptr);
}
Для компактности я опускаю другие определения new и delete. record_alloc и unrecord_alloc - это функции, которые поддерживают связанный список структур, содержащих ptr, строку и файл).
в new.hpp
extern const char* __file__;
extern size_t __line__;
#define new (__file__=__FILE__,__line__=__LINE__) && 0 ? NULL : new
Для g ++ «new» раскрывается только один раз. Ключ - это «&& 0», что делает его ложным и заставляет использовать настоящее новое. Например,
char *str = new char[100];
расширяется препроцессором до
char *str = (__file__="somefile.c",__line__=some_number) && 0 ? NULL : new char [100];
. Таким образом, записываются номер файла и строки, и вызывается ваша настраиваемая новая функция.
Это работает для любой формы new - до тех пор, пока существует соответствующая форма в new.cpp