我不确定我是否会回答你所有的问题,但这里是……
我也使用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 是高级 对象。话虽如此,他们的提供者比删除做了更多的工作。例如,它们还提供视图使用的视图模型(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 的存储库,因为你必须专门化 em> 只是为了让它按照你需要的方式工作。
我的AddressProvider、EmailProvider 和PhoneProvider 本质上是相同的,因为它们实现了IProvider,但是它们都为它们正在使用的对象实例化了一个通用存储库 (Repository<T>)。
此外,您的控制器不应直接与存储库交互,而应通过提供程序间接交互。
我的CustomerProvider 和EmployeeProvider 每个实例都专门为Customer 和Employee 存储库(CustomerRepository、EmployeeRepository),但它们也会实例化其他存储库,例如在构建视图时需要楷模。例如,他们将实例化一个StateRepository,即Repository<State> 或PhoneTypesRepository,即Repository<PhoneType>,他们将使用这些存储库将其他对象/集合传递给视图,以使用下拉菜单或任何。他们还将实例化其他提供程序以进一步帮助构建视图模型,例如 CookieProvider,他们使用该模型获取当前活动的 Cookie 并将其传递给视图模型。
总而言之,它是一个由独立/通用提供程序或存储库组成的网格,它们组合在一起以完成一项专门的任务。
我希望这可以通过另一种编写代码的方式为您提供一些启发,或者至少我希望它可以帮助您更好地理解。
附:如果您想知道Provider 是什么,大多数其他人都选择称他们为Service,但对我来说这个词被误用了,所以我只称他们为Providers,因为他们提供 根据需要具有专用功能或数据的控制器。