ASP.NET MVC C#. Как убрать множество параметров в конструкторе контроллера?
Темка значит следующая. Изучаю я значит Asp.net mvc и думаю... Есть универсальный BaseRepository. В нем представлены универсальные методы, применимые ко всем моделям бд.
public class BaseRepository<T> : IRepository<T> where T : class, IModel, new()
{
protected readonly AppDbContext _appDbContext;
public BaseRepository()
{
}
public BaseRepository(AppDbContext appDbContext)
{
_appDbContext = appDbContext;
}
}
Есть просто Repository, которые наследуется от BaseRepository. В нем представлены уникальные методы для конкретной модели бд. В данном случае - для модели Vacancy
public class VacancyRepository : BaseRepository<Vacancy>
{
public VacancyRepository()
{
}
public VacancyRepository(AppDbContext appDbContext) : base(appDbContext)
{
}
}
Есть RepositoriesUnitOfWork, где создаются репозитории.
public class RepositoriesUnitOfWork
{
private AppDbContext _appDbContext { get; set; }
private VacancyRepository vacancy;
public VacancyRepository Vacancy
{
get
{
if (vacancy == null)
vacancy = new VacancyRepository(_appDbContext);
return vacancy;
}
}
public RepositoriesUnitOfWork(AppDbContext appDbContext)
{
_appDbContext = appDbContext;
}
}
Далее в Startup'e подключается RepositoriesUnitOfWork
services.AddTransient<RepositoriesUnitOfWork>();
Далее этот RepositoriesUnitOfWork можно юзать в сервисах и контроллерах, все прекрасно... Пока сервисов и репозиториев мало. При большом их количестве получается вот такая вот не приятная картина в конструкторе контроллера
public VacancyController(RepositoriesUnitOfWork repositoriesUnitOfWork,
VacancyService vacancyService, BookService bookService,
CatService catService)
Передаем RepositoriesUnitOfWork для использования простых запросов к бд, без дублирования кода в сервисе. Ну и сервисы, которые используются в контроллере. Это. Не. Красиво. И ведь это не самый жирный контроллер, есть примеры пострашней. Что же делать? Очевидно проблема в архитектуре, но другой я пока не знаю... вот я и решил самостоятельно что-нибудь придумать. А что если сделать вот так?
public class DbModel<T, Repos, Serv> : BaseRepository<T>
where T : class
where Repos : class, IRepository<T>, new()
where Serv : class, IService<T>, new()
{
private Repos repository;
public Repos Repository
{
get
{
if (repository == null)
repository = new Repos()
{
Base = base.GetThis()
};
return repository;
}
}
private Serv service;
public Serv Service
{
get
{
if (service == null)
service = new Serv()
{
Base = base.GetThis()
};
return service;
}
}
}
public class BaseRepository<T> : DbSet<T> where T : class
{
protected BaseRepository<T> GetThis()
{
return this;
}
}
public class BookRepository : IRepository<Book>
{
public BaseRepository<Book> Base { get; set; }
public void GetR()
{
}
}
public interface IRepository<T> where T : class
{
public BaseRepository<T> Base { get; set; }
}
public class BookService : IService<Book>
{
public BaseRepository<Book> Base { get; set; }
public void GetS()
{
}
}
public interface IService<T> where T: class
{
public BaseRepository<T> Base { get; set; }
}
А потом в AppDbContext поменять DbSet на подобное
DbModel<Book, BookRepository, BookService> Books { get; set; }
Вкидываем туда тип модели бд, репозиторий и сервис. Теперь можно использовать один класс (AppDbContext) как модель (не бд, а буковка M из MVC) В конструктор идет только один объект из которого очень удобно можно достать нужные методы. Кроме того, из-за того что BaseRepository наследован от DbSet можно переопределять методы DbSet как только вздумается. Удобно. Вопрос следующий. Насколько "правильно" использовать подобную архитектуру? Не нарушает ли это ООП? Есть ли более "правильные" способы убрать миллион параметров в конструкторе контроллера?