开发者

Best way of having Service communicate errors to Controller

开发者 https://www.devze.com 2022-12-20 17:11 出处:网络
When the Service layer is only executing a task (checking if Id exists, sending an email, etc.), what is the best way for it to let the controller know if there were any errors?

When the Service layer is only executing a task (checking if Id exists, sending an email, etc.), what is the best way for it to let the controller know if there were any errors?

Two solutions I can think of:

  1. Always passing in an extra "broken rules" parameter by reference to the methods in the Service layer which it would update if there were any error.

  2. Have the Service raise an exception and having the controller do a try/catch.

Are either one of these two approaches recommended? 开发者_JS百科If not, what approach could I take to have the Service layer let the controller know what something went wrong (such as invalid parameter)?


Your service should collection all the broken rules and after that throw the "BrokenRuleException". Your controller will catch the "BrokenRuleException" and then use the brokenrules to update the user interface.


I created interface:

public interface IModelStateWrapper
{
    void AddModelError(string name, string error);
}

Then I created implementation for every controller:

public class ControllerModelStateWrapper : IModelStateWrapper
{
    private ModelStateDictionary _dictionary;

    public ControllerModelStateWrapper(ModelStateDictionary dictionary)
    {
        _dictionary = dictionary;
    }

    public void AddModelError(string name, string error)
    {
        if (_dictionary[name] == null)
            _dictionary.Add(name, new ModelState());
        _dictionary[name].Errors.Add(error);
    }
}

Every service implements:

public interface IModelWrapperService
{
    IModelStateWrapper ModelWrapper {get;set;}
}

And then I set it in Controller:

public UserController(IUserService service)
{
    _service.ModelWrapper = new ControllerModelStateWrapper(ModelState);
}

IModelStateWrapper is not the best name, because this interface can work not only with Controller.ModelState. Works pretty ok. You can easily replace IModelStateWrapper with mock or other implementation in your service tests. This solution also automatically sets ModelState as invalid.


I think that throwing the BrokenRuleException is a good choice.

Personally, I don't like to put state in a service, it's often a singleton (performed by a DI container), and only has other singletons collaborators (in my case, domain objects).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号