所以我的服务中有一个方法,我将从控制器调用:
public void SendMessage(Message message) {
message.Property = "Random";
try {
// try some insert logic
}
catch (Exception) {
// if it fails undo some stuff
// return the errors
throw;
}
// if there are no errors on the return the operation was a success
// but how do I get the Service generated data?
}
修改
所以问题不在于让我的代码工作,而是使用存储库模式时遇到的问题,同时使用服务层作为“介于”之间用于 DAL 和演示文稿
之间的通信所以我有一个名为DataLibrary
的单独程序集。
DataLibrary
包含我的模型(Message
),我的存储库和服务(MessageService
)
在我的MVC网站中,我通常会有一个具有CRUD功能的控制器。它看起来像这样:
public ActionResult Create(Message message) {
if(ModelState.IsValid) {
db.insert(message);
}
Return View(message);
}
但是通过使用存储库模式,通过服务层进行通信,我改为:
public ActionResult Create(MessageCreateModel message) {
if(ModelState.IsValid) {
MessageService.SendMessage(message.ToDTO());
}
Return View(message);
}
我如何知道操作成功或不成功以及出于什么原因?
如何在上述同时从服务的业务逻辑中检索填充的数据?
我如何在尽可能接近MVC设计模式/关注可扩展性的问题的同时实现上述两个目标?
答案 0 :(得分:0)
您确实没有提供有关您的架构的足够信息,以便回答这个问题。但是,如果您想从SendMessage
方法获取值,则添加返回值而不是void
是一个很好的起点。
答案 1 :(得分:0)
首先,如果只是将工作委托给您的存储库,为什么要通过服务?如果您已正确实现了存储库(即完全抽象),则无需使用该服务。只需直接从控制器调用存储库即可。您可以在我的blog中了解有关存储库模式的更多信息。
但这并没有真正解决这个问题。
那么你如何处理错误?当遇到异常时:Simply do not catch it;)Exceptions are after all exceptions并且您通常无法处理以提供预期结果。
正如我们所说的那样,数据层通常意味着一个稳定的数据库引擎,预计读/写将成功。因此,除了使用异常之外,不需要任何其他错误处理。
在ASP.NET MVC中,您可以使用属性处理事务,并使用try / catch填充模型状态,如here所示:
[HttpPost, Transactional]
public virtual ActionResult Create(CreateModel model)
{
if (!ModelState.IsValid)
return View(model);
try
{
model.Category = model.Category ?? "Allmänt";
var instruction = new Instruction(CurrentUser);
Mapper.Map(model, instruction);
_repository.Save(instruction);
return RedirectToAction("Details", new {id = instruction.Id});
}
catch (Exception err)
{
// Adds an error to prevent commit.
ModelState.AddModelError("", err.Message);
Logger.Error("Failed to save instruction for app " + CurrentApplication, err);
return View(model);
}
}
答案 2 :(得分:0)
我认为您应该首先决定如何设计您的架构。您是否选择面向服务,如果是这样,您的服务方法必须返回通知控制器的东西。因此,将您的服务层视为国家/地区的边界,而另一个国家/地区的边界则是控制器。你必须让这两个国家进行贸易。这可以使用包含返回数据和服务错误等的返回对象来完成。
如果您只想将某些业务逻辑放入服务层,那么您可能不需要独立的层。只需一些松耦合就足够了。因此,您可以返回基本的clr对象或域对象或应用程序对象。在一个非常基本的例子中这样:
//AService service method
public AnEntity ServiceMethod(AFilterViewModel aFilter)
{
//do some validation
try
{
//some transactional operations
}
catch
{
//do some log and rollback it...
throw;
}
var anEntity = _aRepository.GetSomeEntity(x=> x.Something == aFilter.Something);
return anEntity;
}
//controller method
public ActionResult GetSomething(AFilterViewModel aFilter)
{
try
{
var entity = _aService.ServiceMethod(aFilter);
AViewModel model = MapToView(entity);
return View(model);
}
catch
{
return RedirectToAction("Error");
}
}
如上所述,控制器和服务层方法可以共享彼此的对象。它们彼此有界限,它们相互耦合。但是你的架构决定了它们的耦合程度。
您也可以单向执行这些映射。像服务器只有控制器或控制器只服务。如果您不想在服务层中使用viewmodel,则应始终在服务层中进行映射。否则在控制器中进行对象映射。而且也不要忘记将你的viewmodel放到另一个库中,这非常重要。这些就像“价值对象”。