引发UserFriendlyException的替代方法和业务规则验证的异常处理



考虑到抛出异常的成本,另一种方法如下:

public interface IValidationDictionary
{
void AddError(string key, string message);
bool IsValid { get; }
}
public class ModelStateWrapper : IValidationDictionary
{
private ModelStateDictionary _modelState;
public ModelStateWrapper(ModelStateDictionary modelState)
{
_modelState = modelState;
}
public void AddError(string key, string errorMessage)
{
_modelState.AddModelError(key, errorMessage);
}
public bool IsValid
{
get { return _modelState.IsValid; }
}
}
public interface IApplicationService
{
void Initialize(IValidationDictionary validationDictionary);
}
public interface IUserService : IApplicationService
{
Task CreateAsync(UserCreateModel model);
}
public class UserService : IUserService
{
private readonly IUnitOfWork _uow;
private IValidationDictionary _validationDictionary;
public UserService(IUnitOfWork uow)
{
_uow = uow ?? throw new ArgumentNullException(nameof(uow));
}
public void Initialize(IValidationDictionary validationDictionary)
{
_validationDictionary = validationDictionary ?? throw new ArgumentNullException(nameof(validationDictionary));
}
public Task CreateAsync(UserCreateModel model)
{
//todo: logic for create new user
if (condition)
//alternative: throw new UserFriendlyException("UserFriendlyMessage");
_validationDictionary.AddError(string.Empty, "UserFriendlyMessage");
if (other condition)
//alternative: throw new UserFriendlyException("UserFriendlyMessage");
_validationDictionary.AddError(string.Empty, "UserFriendlyMessage");
}
}
public class UsersController : Controller
{
private readonly IUserService _service;
public UsersController(IUserService service)
{
_service = service ?? throw new ArgumentNullException(nameof(service));
_service.Initialize(new ModelStateWrapper(ModelState));
}
[HttpPost]
public async Task<IActionResult> Create([FromForm]UserCreateModel model)
{
if (!ModelState.IsValid) return View(model);
await _service.CreateAsync(model);
//todo: Display ModelState's Errors
}
}

考虑到输入验证(如验证DTO(和业务规则验证之间存在差异https://ayende.com/blog/2278/input-validation-vs-business-rules-validation

Input Validation对我来说就是验证用户输入。一些我认为,人们称"姓名不得为空"是一条商业规则作为输入验证。业务规则验证更加复杂,因为对我来说,业务规则不是"名称不能为空",而是系统中需要动作的状态的定义。这是业务规则的定义:

订单应在30天内付款,此期限可以扩展到最多三次。

是否有任何想法可以发送一些出现在应用程序服务方法的逻辑之间的业务规则验证错误消息

的另一种方法

public class Result
{
public bool Success { get; private set; }
public string Error { get; private set; }
public bool Failure { /* … */ }
protected Result(bool success, string error) { /* … */ }
public static Result Fail(string message) { /* … */ }
public static Result<T> Ok<T>(T value) {  /* … */ }
}
public class Result<T> : Result
{
public T Value { get; set; }
protected internal Result(T value, bool success, string error)
: base(success, error)
{
/* … */
}
}

该方法是一个命令,它不会失败:

public void Save(Customer customer)

该方法是一个查询,它不会失败:

public Customer GetById(long id)

该方法是一个命令,可能会失败:

public Result Save(Customer customer)

该方法是一个查询,可能会使失败

public Result<Customer> GetById(long id)

最新更新