Я пытался реорганизовать свой код с тех пор, как обнаружил, что много копирую и вставляю, чтобы реализовать логику контроллеров веб-API. Вот как выглядели контроллеры до рефакторинга
Контроллер для EducationalGroups
стол:
public class EducationalGroupsController : ApiController
{
public HttpResponseMessage Get()
{
try
{
using (SchoolDbContext entities = new SchoolDbContext())
return Request.CreateResponse(HttpStatusCode.OK,
entities.EducationGroups.Where(g => !g.Is_Delete).ToList());
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.NoContent, e);
}
}
public HttpResponseMessage Post([FromBody] EducationGroup group)
{
try
{
using (SchoolDbContext entities = new SchoolDbContext())
{
group.Create_User = WebApiConfig.CurrUserIdx;
group.Create_Date = DateTime.Now;
entities.EducationGroups.Add(group);
entities.SaveChanges();
var msg = Request.CreateResponse(HttpStatusCode.Created, group);
msg.Headers.Location = new Uri(Request.RequestUri, group.Id.ToString());
return msg;
}
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, e);
}
}
}
Контроллер для EducationalStages
стол:
public class EducationalStagesController : ApiController
{
public HttpResponseMessage Get()
{
try
{
//Notice the only difference here is the *Educational_Stages* object of type DbSet
using (SchoolDbContext entities = new SchoolDbContext())
return Request.CreateResponse(HttpStatusCode.OK,
entities.Education_Stages.Where(s => !s.Is_Delete).ToList());
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.NoContent, e);
}
}
//Same implementation for this method as previous controller
//Only with the difference of the type of the parameter
public HttpResponseMessage Post([FromBody] Education_Stages stage)
{
try
{
using (SchoolDbContext entities = new SchoolDbContext())
{
stage.Create_User = WebApiConfig.CurrUserIdx;
stage.Create_Date = DateTime.Now;
entities.Education_Stages.Add(stage);
entities.SaveChanges();
var msg = Request.CreateResponse(HttpStatusCode.Created, stage);
msg.Headers.Location = new Uri(Request.RequestUri, stage.Id.ToString());
return msg;
}
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, e);
}
}
}
Для еще 8 таблиц требуется еще 8 контроллеров, так что вы понимаете, насколько это избыточно …
Я пытался создать базовый класс для сущностей, которые имеют одни и те же поля, как показано ниже:
public abstract class BaseEntity
{
public int Id { get; set; }
[StringLength(50)]
public string Ar_Name { get; set; }
[StringLength(10)]
public string En_Name { get; set; }
public bool Is_Delete { get; set; }
public int? Create_User { get; set; }
public DateTime? Create_Date { get; set; }
public int? Last_Update_User { get; set; }
public DateTime? Last_Update_Date { get; set; }
}
И унаследовать его от всех сущностей, использующих одни и те же поля:
public partial class Education_Stages : BaseEntity
{
}
А затем создайте базовый класс для контроллеров API, чтобы наследовать от него, как показано ниже, и вот где я не могу найти больше решений для того, что хочу:
public abstract class BaseApiVerbs<T> : ApiController where T : BaseEntity
{
private DbSet<T> dbSet;
public BaseApiVerbs(DbSet<T> _dbSet)
{
dbSet = _dbSet;
}
public HttpResponseMessage Get()
{
try
{
return Request.CreateResponse(HttpStatusCode.OK,
dbSet.Where(t => t.Is_Delete == false));
}
catch (Exception e)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, e);
}
}
public HttpResponseMessage Post([FromBody] T entity)
{
// No Idea how to implement the same logic here without using DbContext...
}
Кроме того, я не знаю, как инициализировать классы контроллеров и передать DbSet
объект соответственно:
public class CityController : BaseApiVerbs<City>
{
SchoolDbContext context = new SchoolDbContext();
public CityController()
: base( /* How would I pass the DbSet object here? */ )
{
}
}
Приемлема ли в этом случае идея копирования и вставки кода? Если нет, как я могу выполнить то, что пытался сделать последние два дня?
Я новичок, поэтому, пожалуйста, не будьте резкими в своих ответах, если вы обнаружили что-то неприятное в моем коде, пожалуйста, отметьте это для меня 🙂
1 ответ
Честно говоря, не пытайтесь изобретать новые способы делать что-то, а вместо этого изучите хорошо задокументированные способы делать что-то, например MediatR и CQRS.
При именовании вещей следуйте рекомендациям Microsoft: в именах свойств, классов и т. Д. Разрешены только буквенно-цифровые символы (исключение составляет подчеркивание в начале частной переменной-члена).
Используйте читаемые имена. Ar_Name
и En_Name
бессмысленны. Create_User
и подобные — это названия методов, а не свойств.