Не уверен, что отвечу на все ваши вопросы, но вот ...
Я тоже использую BaseController
, но я не делаю того, что делает ваш пример. Вот как выглядит мой код (мое приложение также использует DI для конструкторов ...):
public class BaseController : Controller {
private readonly IProvider AddressProvider = null;
private readonly IProvider EmailProvider = null;
private readonly IProvider PhoneProvider = null;
[Inject] // Using Ninject for DI
public BaseController(
AddressProvider AddressProvider,
EmailProvider EmailProvider,
PhoneProvider PhoneProvider) {
this.AddressProvider = AddressProvider;
this.EmailProvider = EmailProvider;
this.PhoneProvider = PhoneProvider;
}
}
А вот мой AdministrationController
, унаследованный от BaseController
:
public class AdministrationController : BaseController {
private readonly CustomerProvider CustomerProvider = null;
private readonly EmployeeProvider EmployeeProvider = null;
[Inject]
public AdministrationController(
CustomerProvider CustomerProvider,
EmployeeProvider EmployeeProvider,
AddressProvider AddressProvider,
EmailProvider EmailProvider,
PhoneProvider PhoneProvider) : base(AddressProvider, EmailProvider, PhoneProvider) {
this.CustomerProvider = CustomerProvider;
this.EmployeeProvider = EmployeeProvider;
}
}
Мой AdministrationController
заботится только о CustomerProvider
и EmployeeProvider
и передает AddressProvider
, EmailProvider
и PhoneProvider
BaseController
.
AddressProvider
, EmailProvider
и PhoneProvider
находятся в BaseController
, потому что я считаю Address
, Email
и Phone
низкоуровневыми объектами. Моя причина в том, что они могут быть связаны с Customer
, Employee
или чем-то еще, что касается базы данных. Итак, вместо того, чтобы иметь несколько методов для Customer
или Employee
для взаимодействия с каждым из их объектов, у меня есть только один. Например:
public class BaseController : Controller {
// GET: /Addresses/{AddressId}/Delete
public void DeleteAddress(
int AddressId) {
this.AddressProvider.DeleteAndSave(AddressId);
Response.Redirect(Request.UrlReferrer.AbsoluteUri);
}
// GET: /Emails/{EmailId}/Delete
public void DeleteEmail(
int EmaildId) {
this.EmailProvider.DeleteAndSave(EmailId);
Response.Redirect(Request.UrlReferrer.AbsoluteUri);
}
// GET: /Phones/{PhoneId}/Delete
public void DeletePhone(
int PhoneId) {
this.PhoneProvider.DeleteAndSave(PhoneId);
Response.Redirect(Request.UrlReferrer.AbsoluteUri);
}
}
И с этим я забочусь о своих низкоуровневых объектах. Имейте в виду, что в моем приложении у меня есть дополнительные методы для дальнейшего управления этими объектами по мере необходимости.
Сейчас в своем AdministrationController
я работаю с CustomerProvider
и EmployeeProvider
. Они более специализированы, потому что я считаю Customer
и Employee
объектами высокого уровня. При этом их провайдеры делают немного больше, чем Delete. Например, они также предоставляют модели представлений, используемые представлениями (durp ...):
public class AdministrationController : BaseController {
public ActionResult Customer(
int CustomerId) {
return this.View(this.CustomerProvider.GetView(CustomerId));
}
public AciontResult Customers() {
return this.Veiw(this.CustomerProvider.GetAllView(CustomerId));
}
public ActionResult CustomerAddresses(
int CustomerId,
Address Address) {
if (ModelState.IsValid) {
this.CustomerProvider.AddAddressAndSave(CustomerId, Address);
};
return this.RedirectToAction("Customer", new {
CustomerId = CustomerId
});
}
public ActionResult Employee(
int EmployeeId) {
return this.View(this.EmployeeProvider.GetView(EmployeeId));
}
public ActionResult Employees() {
return this.View(this.EmployeeProvider.GetAllView());
// OR
// return this.View(this.EmployeeProvider.GetActiveView());
// OR
// return this.Veiw(this.EmployeeProvider.GetInactiveView());
// ETC...
// All of these return the exact same object, just filled with different data
}
public RedirectToRouteResult EmployeeAddresses(
int EmployeeId,
Address Address) {
if (ModelState.IsValid) {
this.EmployeeProvider.AddAddressAndSave(EmployeeId, Address);
// I also have AddAddress in case I want to queue up a couple of tasks
// before I commit all changes to the data context.
};
return this.RedirectToAction("Employee", new {
EmployeeId = EmployeeId
});
}
}
Рекомендуется ли иметь только один репозиторий на контроллер?
Я скажу нет, потому что ваши репозитории будут работать только для того объекта, для которого они созданы. У вас не может быть (ну, вы можете, но это просто плохо ...) репозитория, который обрабатывает Address
, Email
и Phone
одновременно, потому что вам придется специализироваться только для этого работать так, как вам нужно.
Мои AddressProvider
, EmailProvider
и PhoneProvider
по сути одинаковы, потому что они реализуют IProvider
, однако каждый из них представляет собой общий репозиторий (Repository<T>
) для объекта, с которым работают.
Кроме того, ваш контроллер не должен напрямую взаимодействовать с репозиториями, а косвенно через поставщиков.
Мои CustomerProvider
и EmployeeProvider
для каждого экземпляра являются специализированными репозиториями для Customer
и Employee
(CustomerRepository
, EmployeeRepository
), но они также являются экземплярами других репозиториев, которые им понадобятся, когда они, например, создают модели представлений. Например, они создадут экземпляр StateRepository
, который равен Repository<State>
, или PhoneTypesRepository
, который равен Repository<PhoneType>
, и будут использовать эти репозитории для передачи дополнительных объектов / коллекций в представление для создания форм с раскрывающимися списками или чего-то еще. Они также будут создавать экземпляры других поставщиков, чтобы помочь в построении модели представления, такой как CookieProvider
, который они используют для получения текущего активного Cookie
и передачи его в модель представления.
В общем, это сеть независимых / универсальных поставщиков или репозиториев, которые объединены для выполнения специальной задачи.
Я надеюсь, что это прольет вам свет на альтернативный способ написания кода, или, по крайней мере, я надеюсь, что это просто поможет вам немного лучше понять.
P.S. Если вам интересно, что такое Provider
, большинство других людей предпочитают называть их Service
, но для меня это слово используется неправильно, поэтому я просто называю их Provider
s, потому что они предоставляют контроллеру специализированные функции или данные по мере необходимости.
person
Gup3rSuR4c
schedule
05.12.2010