|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 2010-06-30 19:29:39
Posts: 104,
Visits: 314
|
|
efim (2010-03-04) I avoid constraints whenever possible because they cry after something bad happened. I need then some means to go back to a valid state, and it is not always good if user should do it.
I used to try to implement business rules / constraints on setters so the domain objects remained constrained, but I realized it was just impractical to do. I found the IDataErrorInfo interface in .NET and decided this was the way to enforce my business rules. The methodology is to allow your objects to be in error but to have a standard way to communicate the errors. You always know if a domain object is valid by using the interface on the object. If the user gets into an error state that cannot be resolved, Eco provides nice undo features to rollback changes to a valid state. If you never allow invalid objects to be saved, you are guaranteed to have valid objects stored in the server. For your specific situation I would enforce the business rule with IDataErrorInfo methodology and also put a check on the user interface to disable the delete button when there is only one record in the detail. efim (2010-03-04) BTW, thank you for the tip to use IDataError. I didn't closely use it before. I don't want however to use too specific .Net features in the business logic layer, because it belongs closer to PIM and it can be more difficult to migrate it in the future to other platforms.
One of the beauties of the IDataErrorInfo interface is that it is very simple. It would be very easy to port to any platform. efim (2010-03-04) I don't understand in what concern throwing exception can be problem for data binding.
In winforms an exception that is thrown during a data-bind setter operation is eaten by the data binding framework. No error is thrown and the user cannot leave the control the error occurred in. I think WPF has similar behavior. Brian .
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: Today @ 05:01:26
Posts: 129,
Visits: 4 817
|
|
| I suppose I should get off my but and make a post with my IDataErrorInfo Eco wrapping classes. I have a very nice class that runs the constraints and post the broken ones via the interface. The biggest reason I never did post it is that it si not really done the way we would want it due to a missing feature (see below) in the Eco Modlr but it is actually very usable the way it is and so I will make a new project, port the wrapper classes over to it and then post it. Look for it soon.... The missing feature is Property Constraints. Inside the Eco model, each property actually has a Constraint collection but the modlr does not provide any access to it. I ended up using the Tag Properties collection to store them. Work fine but there is no pre-runtime way to validate your OCL.
Rick Weyrauch
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: Today @ 11:08:06
Posts: 256,
Visits: 2 317
|
|
efim (2010-03-03) I can't agree with the validation point "update database". It would mean only the objects in database are valid, but what if these are not yet saved andthe user rely on the valid state? Normally an invariant should be validated after each publicmethod call, not only Update DB, because of that I don't like invariants.
In the case where you need two dates (for example) to always be in sync even before persisting you can make their setters private and have a method which sets both dates at the same time. But that is beside the point really, your problem IS a persistence problem.
====
Pete
|
|
|
|
|
Forum Member
      
Group: Forum Members
Last Login: 2 days ago @ 23:13:22
Posts: 47,
Visits: 243
|
|
RickWeyrauch (2010-03-05) ...
The missing feature is Property Constraints. Inside the Eco model, each property actually has a Constraint collection but the modlr does not provide any access to it. I ended up using the Tag Properties collection to store them. Work fine but there is no pre-runtime way to validate your OCL.
I just provide two implementations of my own IConstraint interface - one for the modelled constraints (holds IExpression) and another for the property "constraints" (holds IProperty). I add property constraints only if: // pseudo C# code follows
ValueForTag("Eco.AllowNULL", "False") == "False" && ValueForTag("Eco.AsNullable", "False") == "False" && PropertyInfo.PropertyType is nullableType .
I agree that property constraints (not null) needs several checks, which is strange.
/Pawel
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: Today @ 05:01:26
Posts: 129,
Visits: 4 817
|
|
| The value in Modlr doing it natively is that bad OCL will be found via the Verify Model checks. It is the same argument for why the View Models being incorporated directly by C.O. in Modlr is so valuable. I need pre-runtime (and preferably compile time but I will take any pre-runtime) validation of my OCL. If it does not break until runtime, then the OCL is a liability == to it's assest. Maybe that would be another good feature idea...... A call back interface on Verify Model where the application developer can say whether or not any non-Modlr OCL is still valid against the current model. Then, if I make some fancy-schmancy OCL based extension, I have an opportunity to run it against the model. Of course, I could make such a thing now but this callback would (should, could) have an IVerifyOclService that is already pointing at the model environment (Eco must have it for it self to verify OCL) that I could just toss my OCL at so that I do not have to do all the work of getting a "Verify the Model" environment setup. Capable Objects - Aren't you glad I am back on the Eco bandwagon? Three new feature request a week! The problem is, it is so easy to love that I just want to love it to death!!!
Rick Weyrauch
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 2010-05-15 22:36:10
Posts: 188,
Visits: 451
|
|
[b]Peter Morris (2010-03-05)[/b In the case where you need two dates (for example) to always be in sync even before persisting you can make their setters private and have a method which sets both dates at the same time.
Exactly this solution I would prefer no matter with persistance or not because it would give guarantee the object space is always in valid state. [b]Peter Morris (2010-03-05)[/b your problem IS a persistence problem. It would be in a multi-client environment, but for single-client I make logically no difference between persisted and not (yet) persisted object. Why should I do?
/Efim
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 2010-05-15 22:36:10
Posts: 188,
Visits: 451
|
|
brian (2010-03-05)
For your specific situation I would enforce the business rule with IDataErrorInfo methodology and also put a check on the user interface to disable the delete button when there is only one record in the detail. . I had a look into IDataErrorInfo and must admit I'm not much impressed;-) Quite simple - yes, but I guess suites for realtively simple validation cases one instance (property) <-> one possible problem. In any other case the information get lost when you e.g. concat 2 or more error messages in one string, not talking about other exception data as number, inner exception and so on. But the main problem with this approach, not specially concerning IDataErrorInfo is that you need some smart decision rools that should be able to leave an invalid state and go to some reasonable valid one. The Undo is not necessary always the best choice as it can lead to deadlocks. I can agree if an invalid state is entered in an UI in "Idle"-state, your decision rule could be (and Is in most cases) a User that is smart enough to find the best choice. But what if not? That is why I used not to allow invalid states in an application in general, but rather to take care about always valid transitions between states. It is better not to do sins than later regret and try to correct these isn't it?;-)
/Efim
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 2010-06-30 19:29:39
Posts: 104,
Visits: 314
|
|
| You cannot prevent a user from entering invalid data in a control by coding the rules in the model. No matter what you do in the model, the user can still enter invalid data into a text box. Either you let them move on giving them an error on the text box control or you prevent them from leaving the control until they correct the problem. The later is very burdensome or might be impossible for the user to do. So I choose to do the former and allow the user to leave the control but give them an error indicating something is wrong. The IDataErrorInfo does this for you automatically.
If it is possible to keep a user from entering into an error condition by disabling a button or control, I will do so explicitly in the form. The prevention logic is different from the constraint logic. The constraint logic indicates an error condition exists. Whereas the prevention logic indicates that an action/command will cause an error condition. A robust application needs both.
WPF has a nice concept where commands call a CanExecute method to determine if the command can be executed. The logic that determines the CanExecute should be programmed in the domain object. So the CanExecute event code should call into the domain object to determine the result.
It would be very nice if we could bind the wpf commands to the eco domain object. Rick has done some things interesting things to accomplish this. Maybe he could chime in. 
Brian
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: 2010-05-15 22:36:10
Posts: 188,
Visits: 451
|
|
| All you mention should belong to application logic that handles the wrong inputs of user, listens to events in buisiness logic, accomplishes conversion-stuff in Databinding (in WPF for ex.) and so on. Specially in WPF the MVVM pattern is here that stuff. Also the Commands implementation - it is also the matter of application layer, not the business logic, because it can differ from app to app whether you can edit an object or not, think about priviledges for ex. The only consideration of using constraint logic on the model level for me is multi-client architecture - it is because you can never be sure your data are correct indeed before you save these in DB.
/Efim
|
|
|
|
|
Supreme Being
      
Group: Forum Members
Last Login: Today @ 05:01:26
Posts: 129,
Visits: 4 817
|
|
| I will add my Command to Eco binding classes in the sample I am putting together. It really shines for connecting WBF buttons to Eco State Triggers. Right now the sample is over at C.O. getting "looked at" for a little issue I had with it. As soon as we can resovel the issues I will post the sample here.
Rick Weyrauch
|
|
|
|