MarimerLLC / cslaforum

Discussion forum for CSLA .NET
https://cslanet.com
Other
31 stars 6 forks source link

Stereotype for TaxCalculator object #731

Open Chicagoan2016 opened 5 years ago

Chicagoan2016 commented 5 years ago

Hi All, I have to implement a TaxCalculator class, coincidentally Rocky has talked about a 'TaxCalculator' object on P-7 of Creating business object book.

What stereoptype should I use to implement such object? This object will be mainly used in 'using' relationship by other objects. Also the Tax calculated will depend on location, price among other things.

I thought about EditableRoot but where will the tax calculations take place? In of the business rules? If so, the businessrule won't run until we 'save' the object and there is no 'saving' within the TaxCalculator object itself. Any ideas please?

kind Regards

Version and Platform CSLA version: 4.7.100 OS: Windows, Linux, iOS, Android, etc. Platform: WinForms, WPF, ASP.NET Core, MVC, Xamarin, etc.

hurcane commented 5 years ago

Is TaxCalculator going to be independently updating data? If not, it may not need to be a CSLA stereotype at all.

Chicagoan2016 commented 5 years ago

@hurcane , No, TaxCalculator is not going to update data but if I write it as Non-Csla code, I am worried about potential 'side effects' of using non-serialize able code with Csla, I try to avoid it.

rockfordlhotka commented 5 years ago

The question I'd have is whether this is a stateful object, a rule, or a stateless service?

If it is a stateful object where you set a bunch of properties and it uses business rules to calculate the tax then it would probably derive from BusinessBase so you get the rules engine.

If it is a rule then it would subclass BusinessRule and do its calculation as a rule implementation, probably triggered by the parent object that contains the line items with various quantity/price/taxable values.

If it is an algorithm you invoke (from a class or rule) then you can implement it as a stateless service - a class with a method that accepts a parameter (message), does its calculations, and returns its result (message).

Chicagoan2016 commented 5 years ago

Thank you @rockfordlhotka , In the third scenario you described, where implemented as a stateless service, should it be a Csla based object?

Kind regards

rockfordlhotka commented 5 years ago

Sorry, in the service case it would typically not be serializable, nor would it subclass any CSLA base class. It is just an algorithm implemented in a method.

I'd make it an instance method, even though realistically you'll just call it and be done, because if it is an instance method you get some benefits:

  1. Unit testing is easy
  2. If necessary you can use a provider or IoC pattern to swap out that type for other tax calculator types (perhaps for regional or international scenarios or testing)
rockfordlhotka commented 5 years ago

Having written a number of point of sale/order entry/invoicing type systems though, I'd strongly suggest looking at this as a rule.

The reason being that you have line items right? Each line item needs to calculate its own tax any time the quantity/price/taxable properties change - so implementing as a rule is very easy in this context.

Chicagoan2016 commented 5 years ago

Thank you @rockfordlhotka , I really like the idea of implementing it as business rule but I am not sure if Csla would let us make the business rule 'optional' in a sense that if this particular business rule for calculating tax is broken, I would still like to save the main business object.

kind regards

rockfordlhotka commented 5 years ago

I think your view of business rules is too limited. Yes a business rule can be a validation rule, but they are so, so, so much more! They can be algorithms, calculators, etc.

Chicagoan2016 commented 5 years ago

On second thought :), could I use context.AddSuccessResult() in TaxCalculator business rule for cases where the 'required' arguments for the TaxCalculator are not supplied but we still want to save the object?

Kind regards

jonnybee commented 5 years ago

In sync rules the rule engine will automatically call context.AddSuccessResult() if the rule hasn't already added any result. IE: AddSucessResult is not mandatory in sync rules - only for async rules.

Only AddErrorResult() will make the object invalid (ie: any broken rules with severity Error). You can also consider to use AddInformationResult or AddWarningResult to show messages and the object is still valid for Save.

Chicagoan2016 commented 5 years ago

Thank you @jonnybee