我为一个不太实用的呼叫中心应用程序构建了一个简单的基于MVC3的票证入口站点,并试图重构我的原型以更好地遵循设计模式,部分原因是为了使其更易于维护,但主要是作为一种学习行使。 除了允许选择各种资源类型的几个面板之外,面向用户的视图是由基本用户信息组成的表单。每种资源类型(硬件,软件等)都以相同的方式显示:使用带有添加/删除按钮的双重可过滤列表框,可选的“对齐”文本区域,有条件地显示所请求的资源是否需要对齐,以及一般注释。 我为各个面板构建了以下ViewModel:
public class RequestableList
{
// list of requestable items ids requiring justification
private List<string> _restrictedItems = new List<string>();
public List<string> RestrictedItems
{
get { return _restrictedItems; }
set { _restrictedItems = value; }
}
// the key-value pairs from which to populate available items list
private Dictionary<string, string> _availableItems = new Dictionary<string, string>();
public Dictionary<string, string> AvailableItems
{
get { return _availableItems; }
set { _availableItems = value; }
}
// item ids requested by user
private List<string> _requestedItems = new List<string>();
public List<string> RequestedItems
{
get { return _requestedItems; }
set { _requestedItems = value; }
}
}
根据需要,主ViewModel由多个RequestableLists组成:
public class SimpleRequestViewModel
{
public UserInfo userInfo { get; set; }
public RequestableList Software {get;set;}
public RequestableList Hardware {get;set;}
public RequestableList Access {get;set;}
public string SoftwareAdditionalInfo { get; set; }
public string HardwareAdditionalInfo { get; set; }
public string AccessFileMailShare { get; set; }
public string AccessAdditionalInfo { get; set; }
public string SoftwareJustification { get; set; }
public string HardwareJustification { get; set; }
public string AccessJustification { get; set; }
public string Comment { get; set; }
}
我为SimpleRequestViewModel(及其变体)创建了一个强类型视图,并为RequestableList创建了一个强类型的EditorTemplate,它连接了双列表框,过滤和jquery。所有渲染都很好并且正在运行,但代码目前闻起来。
发布到控制器时,如果模型有效,我必须将其翻译成可读的文本说明,以便在呼叫中心应用程序中创建新的票证。将控制器执行转换为可读文本感觉不对,但在尝试设计另一个类来转换视图模型时遇到了障碍。
我考虑直接在ViewModel中覆盖ToString(),但不喜欢那里的业务逻辑(条件渲染),再次发布后,ViewModel不包含列表框中所选项目的文本,因此它需要访问数据模型。 将发布值转换为文本,因为它当前在控制器中处理,因为它在switch语句中处理。控制器获取每个发布的RequestableList,并在构建新的票证描述之前填充原始的“可用”字段。
switch (requestCategory)
{
case RequestableCategory.Software:
itemList = sde.GetSoftware();
break;
case RequestableCategory.Hardware:
itemList = sde.GetHardware();
break;
case RequestableCategory.Access:
itemList = sde.GetAccess();
break;
case RequestableCategory.Telecom:
itemList = sde.GetTelecom();
break;
default:
throw new ArgumentException();
}
所以,我的问题:
同样,我希望这对我来说是一次学习经历,并且非常愿意在需要时提供额外的信息或描述。
答案 0 :(得分:1)
一些建议:
摘要将呼叫中心提交到自己的类中的逻辑。提供(来自控制器)访问呼叫中心DB所需的任何依赖关系。使用重载处理各种类型的视图模型有不同的方法。据推测,这些描述来自数据库,因此您可以根据此类中的值从数据库中提取描述。此类还可以负责为显示操作构建视图模型。请注意,使用此模式,类可以直接与数据库进行交互,通过存储库,甚至通过Web服务/ API进行交互。
如果性能是第二次从DB查找描述时出现问题,请使用实现某些缓存的存储库模式。我怀疑除非您的呼叫中心非常庞大,否则它将不会是优化查询逻辑的地方。存储库可以是控制器传递给提交类的东西。
如果您不需要直接在控制器中访问数据库,请考虑直接将代理类作为依赖项传递。
看起来像是:
private ICallCenterBroker CallCenterBroker { get; set; }
public RequestController( ICallCenterBroker broker )
{
this.CallCenterBroker = broker;
// if not using DI, instantiate a new one
// this.CallCenterBroker = broker ?? new CallCenterBroker( new CallCenterRepository() );
}
[HttpGet]
public ActionResult CreateSimple()
{
var model = this.CallCenterBroker.CreateSimpleModel( this.User.Identity.Name );
return View( model );
}
[HttpPost]
public ActionResult CreateSimple( SimpleRequestViewModel request )
{
if (Model.IsValid)
{
var ticket = this.CallCenterBroker.CreateTicket( request );
// do something with ticket, perhaps create a different model for display?
this.CallCenterBroker.SubmitTicket( ticket );
return RedirectToAction( "index" ); // list all requests?
}
return View();
}