У меня странная ситуация. Мне нужно использовать Entity Framework 6.2 для моего основного приложения .net.
Обычный контроллер
public class SampleApiController : BaseController
{
// use _repo and other stuff
}
Базовый контроллер
public class BaseController : Controller
{
protected IRepo_repository;
public BaseController(IRepo repository)
{
_repository = repository;
}
public BaseController() : this(null)
{
}
}
Приложение DBContext
public class SampleContext : DbContext
{
public SampleContext(string connectionString)
:base(connectionString)
{
try
{
this.Database.Log = (s) => System.Diagnostics.Debug.Write(s);
}
catch (Exception e)
{
//CurrentLogger.Log.Error(e);
}
}
public DbSet<Test1> Test1s { get; set; }
public DbSet<Test2> Test2s { get; set; }
}
Интерфейс репозитория
public interface IRepo
{
// methods definition
}
Класс репозитория
public interface Repo : IRepo
{
// methods implementation
}
Startup.cs -> метод ConfigureServices
services.AddScoped<SampleContext>((s) => new SampleContext(configuration["ConnectionStrings:SampleApp"]));
services.AddScoped<IRepo, Repo>();
На этом изображении вы могли видеть, что параметр репозитория пуст ... не инициализирован с помощью экземпляра Repo ... (!!! На этом рисунке IRepo - это IRepositoryBase)
Решение !
Как сказали CodeNotFound и Riscie в комментариях, проблема заключалась в том, что BaseController был инициализирован с помощью null ... Спасибо, ребята!
Репо - это интерфейс .. он должен быть классом и реализовывать IRepo
Для чего нужен конструктор по умолчанию? Я думаю, что DI использует хранилище по умолчанию, которое вызывает this(null)
. Именно здесь вы получаете значение null
. Поставьте там точку останова и проверьте.
Единственная зарегистрированная вами служба - это IRepo => Repo
, но вы вводите IRepositoryBase
. Вы не сказали контейнеру DI, как обращаться с IRepositoryBase
.
FWIW, не используйте шаблон репозитория. Шаблон репозитория предназначен для работы с чем-то низкоуровневым, например с SQL. ORM, как и Entity Framework, уже реализует шаблон репозитория. Вот какие у вас DbSet
. Обертывание этого в репозитории - это просто бесполезная абстракция, которая добавляет дополнительную энтропию к вашему коду (больше для поддержки, больше для тестирования) без каких-либо преимуществ (в любом случае у вас все еще есть зависимость от EF).
Попробуй это:
Интерфейс репозитория
public interface IRepo
{
// methods definition
}
Класс репозиторияЯ изменил это с интерфейса на класс и заставил его реализовать интерфейс IRepo.
public class Repo : IRepo
{
// methods implementation
}
Редактировать:Также удалите второй конструктор
public class BaseController : Controller
{
protected IRepo_repository;
public BaseController(IRepo repository)
{
_repository = repository;
}
//second constructor most likely introduces the problem
}
извините, я забыл поместить это в этот образец. В коде это так.
в вашем конструкторе BaseController
(на скриншоте) вы также создаете экземпляр IRepositoryBase
вместо IRepo
.
кроме того, почему у вас есть конструктор, инициализирующий ваш BaseController значением null? (см. мою правку)
Обычно вы передаете IRepo
от SampleApiController
к BaseController
.
Насколько я понимаю, вам не нужен конструктор аргументов в BaseController
. Если это так, вы можете удалить его, чтобы _repository
не был null
.
public class SampleApiController : BaseController
{
public SampleApiController(IRepo repository)
: base(repository)
{
}
}
public class BaseController : Controller
{
protected IRepo _repository;
public BaseController(IRepo repository)
{
_repository = repository;
}
/*public BaseController() : this(null)
{
}*/
}
public interface IRepo
{
// methods definition
}
ваше репо не реализует интерфейс IRepo