0

所以我的服务中有一个方法,我将从控制器调用:

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?
    }

编辑:

所以问题不在于让我的代码正常工作,而是我在使用服务层作为DALPresentation之间通信的“中间人”时使用存储库模式时遇到的问题

所以我有一个单独的程序集,称为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 设计模式/对可扩展性的关注点分离的同时实现上述两者?

4

3 回答 3

0

您确实没有提供足够的关于您的体系结构的信息来回答这个问题。但是,如果您想从SendMessage方法中返回一个值,添加一个返回值而不是void一个不错的起点。

于 2013-04-29T15:39:32.373 回答
0

首先,如果只是将工作委派给您的存储库,您为什么要通过服务?如果您已经正确地实现了您的存储库(即作为一个完整的抽象),则无需使用该服务。只需直接从您的控制器调用存储库。您可以在我的博客中阅读有关存储库模式的更多信息。

但这并不能真正解决问题。

那么如何处理错误呢?当涉及到异常时:不要捕获它;)异常毕竟是异常,不是您通常可以处理以提供预期结果的东西。

正如我们所说的数据层通常意味着一个稳定的数据库引擎,预计读/写将成功。因此,除了使用异常之外,不需要任何其他错误处理。

在 ASP.NET MVC 中,您可以使用属性处理事务并使用 try/catch 填充模型状态,如下所示

[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);
    }
}
于 2013-04-29T20:10:53.690 回答
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");
     }
}

正如您在上面看到的,控制器和服务层方法可以共享彼此的对象。它们彼此有界限,并且它们耦合在一起。但是您的架构决定了它们的耦合程度。

您也可以仅以一种方式进行这些映射。仅对控制器提供服务或仅对控制器提供服务之类的东西。如果你不想在服务层使用你的视图模型,你应该总是在服务层做映射。否则在控制器中进行对象映射。并且不要忘记将您的视图模型放入另一个库中,这非常重要。这些类似于“价值对象”。

于 2013-04-30T21:38:06.143 回答