开发者

Validation When Using MVVM (WPF) with a DDD-Based Model

A common MVVM/WPF approach is to data-bind the UI's controls directly to the underlying model object. The model object may contain its own validation logic (perhaps exposed via IDataErrorInfo) or may be validated by a helper class checks a model object instance for errors. In either case, at times the model have invalid data in it and so be in an invalid state.

However, in the DDD world, the model is never to be in an invalid state. How do you suggest performing validation when using WPF and DDD?

Thanks,

B开发者_开发问答en


I don't think the View in MVVM should be binding directly to the domain model, it really should be binding to a View Model instead. Then the View Model can be in an "invalid" state which can be reflected through IDataErrorInfo. Only later when a user operation (e.g. Save, OK, Apply) applies this to the underlying domain model should the domain model enforce validity, you can also prevent the apply by not allowing the operation in the UI.

Although I must say I've found that it's not always easy to do this without duplicating the validation logic to some extent.


I'm tending to think that a facade or similar layer should be used as the MVVM "model." This facade can be in an invalid state (unlike the DDD model). For validation, it can either contain its own logic or a tool like FluentValidation can be used. Once it is in a valid state, its "do action" function can be called. This will pass the data in the facade to the underlying DDD model. With this approach, at no point does the DDD model encounter invalid data.

With this approach, the facade and its validation logic could be used by multiple view/view model pairs, eliminating the validation logic duplication present when each view model does its own validation.


Validation belongs in your business logic (domain model). I suggest taking a look at FluentValidation for .NET.

I've actually had good luck having the ViewModel setter call the underlying Model object, and letting FluentValidation throw an exception. If you're using a WPF TextBox, the binding will keep working, but the TextBox will show a red outline (assuming you've used the syntax where the TextBox updates the ViewModel on each and every keystroke). Just don't throw an exception in the getter or you'll break the binding.

It's better to route all your communication from the ViewModel to the Model through some intermediary (I introduced a Presenter, but this can be as simple as passing the Model operation as a lambda to a callback on some mediator). When an exception happens while operating on the Model, the Presenter catches the exception and displays a friendly message to the user with the details from the exception. FluentValidation produces really nice default error messages for this purpose.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜