views:

76

answers:

4

I'm trying to come up with a reusable warning piece for the business objects in a project I'm working on. Before saving one of our business objects, sometimes we need to warn the user of what the potential impacts are. Say my business object was named "Company". Company.Delete() will get rid of the company and not really care about what happens. That particular Company may have 10,000 employees that would be pretty disappointed if it was that easy to put them out of work by accident...

So the UI requires a way to see something like:

  • Deleting "Company A" will put 10,000 workers on the streets.
  • Deleting "Company A" will leave 1,000,000 shareholders with useless stocks.

So I could just make a function like Company.GetWarnings() that returns some strings to display, but I want something a bit better than that. If Company.GetWarnings() returned the first warning above, I would want the UI to be able to know what that warning means. For example, if the first warning were to appear, the UI would know what it means and handle the situation by providing a link like:

  • Deleting "Company A" will put 10,000 workers on the streets.
    • Would you like to find new work for these employees? 'Click Here'

Or perhaps another business object would use Company.GetWarnings() and knowing that some workers would be put out of work, it could automatically send out severance packages. You get the idea...

So I guess the requirement sounds pretty easy, but I'm getting kind of lost in the minor details. Mainly, what kind of structure could I give GetWarnings() so that it returns:

  1. The warning message.
  2. Some way to identify what kind of message it is.

Leaving me to my question:

Does anyone have any best practices, examples, or suggestions to implement this kind of warning system? My main concern is with #2. There will be a ton of different kinds of warning messages, so I don't want to just return say...a Dictionary where the int is an Id of the type of warning. That would get hard to manage fast.

Thanks for any advice you can give.

A: 

If you are able to use 3rd party frameworks...I would recommend using CSLA.net. It is a very nice framework for business logic. If you can't use it for this project, you could at least take a look at the source code to see how he does warnings in the business rules. The source code is provided for free.

Dismissile
+1  A: 

Hey Ocelot, in my opinon this isn't a data driven concern and does also not rely to the business object itself. You need some kind of ActionValidator who checks business logic and takes care of these checks.

MacX

MacX
@MacX - Can you explain in a bit more detail? The warnings very much depend on the business object, because it is the new/changed properties of the object that drive what warnings come up.
Ocelot20
+2  A: 

I guess the possible types of warnings would be quite limited ... Maybe an Enum would be a good idea ?

enum WarningType{
    MayPutWorkersOnTheStreet,
    WillNotPleaseStakeholders
    /*...*/
}

You could define a small class (actually it could be a generic Warning<T> , T being Company or something else, and you could keep track of the source of the error.

public class Warning<T>{
    public Warning(WarningType type, String msg, T source){
         //you get the idea */  
    }
}

And then your validation would generate a list of Warnings like this

public IEnumerable<Warning<Company>> GetWarnings(){
   // something here
}

This is just a quick idea ...

tsimbalar
@tsimbalar - I was thinking about using Enums, but the number of warnings will actually be pretty large. Limiting the types of warnings to the class they pertain to is a good idea though. Upvoting for now, will accept later if no better ideas come along.
Ocelot20
@Ocelot20 : yes, I actually saw the constraint about the big number of warnings a bit too late, while re-reading the question after posting an answer ... I'm interested in the proposed answers, though ! :-)
tsimbalar
+1  A: 

You can use polymorphism to define an abstract warning and a hierarchy of concrete warnings:

abstract class Warning {
  public String Description { get; protected set; }
  public abstract IEnumerable<Consequence> Consequences { get; }
  public abstract IEnumerable<Action> Actions { get; }
}

class CompanyDeletionWarning : Warning {
  public override IEnumerable<Consequence> Consequences { get { ... } }
  public override IEnumerable<Action> Actions { get { ... } }
}

The challenge is to come up with an abstract base class that is general enough to handle all the possible warnings you have. You may have to also use this approach in the aggreated objects, e.g. Action could be an abstract base class with an Execute method. You could then create a concrete FindNewWorkForEmployeesAction.

If you prefer you can use interfaces instead, e.g. IWarning.

Martin Liversage