a way to abstract the success/failure of a subprocess - c#

I'm processing messages from an MSMQ.
For each message there are ten steps such as :
VerifyDates
VerifyPatientInformation
VerifyClinicalInformation
If there is a failure in any one of the three steps, I would like to throw out the message.
Can someone point to a SOLID example demonstrating this principal? I'm not sure how to structure my classes.
For example
public class VerifyDates()
{
private validateSomething ValidateSomething();
public VerifyDates()
{
validateSomething = new ValidateSomething();
}
public bool Verify()
{
validateSomething.IsValid();
}
}
Assuming that VerifyDates() is part of my processing logic, should I be adding a public field to the class bool Flag that returns whether or not to continue processing?
Perhaps I should add an Interface IHasFlag where every class that is used within my processing logic has a Flag that I check at the end to see whether or not to continue message processing?
Processing messages would go something like this
public void ProcessMessages()
{
var verifyDates = new VerifyDates();
if(!verifyDates.IsValid)
{
return;
}
//continue processing
//but every step of the process I would need to check IsValid for that specific class
}
How do you abstract the success/failure of every step within a sequential process?

You could use a fluent API. Something similar to the following:
public interface IFluentValidation<T>
{
bool IsValid { get; }
T ObjectToValidate { get; }
}
internal class FluentValidation<T>: IFluentValidation<T>
{
public bool IsValid { get; }
public T ObjectToValidate { get; }
public FluentValidation(bool isValid, T target)
{
Debug.Assert(target != null);
IsValid = isValid;
ObjectToValidate = target;
}
}
And now build the following extension methods:
public static IFluentValidation<T> ValidateBy<T>(this T target, Predicate<T> validator)
{
if (target == null) throw new ArgumentNullException(name(target));
if (validator == null) throw new ArgumentNullException(name(validator));
if (validator(target))
return new FluentValidation<T>(true, target);
return new FluentValidation<T>(false, target);
}
public static IFluentValidation<T> AndBy<T>(this IFluentValidation<T> target, Predicate<T> validator)
{
if (validator == null) throw new ArgumentNullException(name(validator));
if (!target.IsValid)
return target;
if (validator(target.ObjectToValidate)
return target;
return new FluentValidation<T>(false, target.ObjectToValidate);
}
Implementing an OrBy is trivial as a AndFinallyBy if you want to return the validated object and not a IFluentValidation<T>.
And you would use it like this:
var validated = myObject.ValidateBy(t => //whatever needs to checked t.ObjectToValidate.DateIsValid)
.ThenBy(t => ... //whatever needs to be checked t. ObjectToValidate.PatientIsValid)
.ThenBy(t => ... //t.ObjectToValidate .ClinicalInformationIsValid)
.IsValid;
You can also embellish this a little more and add optional custom error messages in each validation step; public static IFluentValidation<T> AndBy<T>(this IFluentValidation<T> target, Predicate<T> validator, Func<T, string> failureMessageProvider = null) and add the corresponding property string ValidationFailedMessage { get; } to IFluentValidation

Related

Change value of property depending another in class

I have a class named ValidationsResult with this properties:
public class ValidationsResult
{
public bool IsValid { get; set; }
public string[] Errors { get; set; }
public void AddError(string error)
{
Errors.Append(error);
}
}
But I want that the property IsValid to be read only, and depending if the object has Errors or not modify that property automatically.
How can I do that?
public class ValidationsResult
{
public bool IsValid { get => Errors != null && Errors.Length == 0; } // no errors = valid
public string[] Errors { get; set; }
public void AddError(string error)
{
Errors.Append(error);
}
}
That will make it readonly and it will tell you if you have errors
Based on the comment, yes. Better if you designed it in the following fashion.
public class ValidationsResult
{
public bool IsValid { get => Errors.Count == 0; } // or !Errors.Any()
public List<string> Errors { get; } = new List<string>();
public void AddError(string error)
{
Errors.Add(error);
}
}
You initialize the errors but outside consumer can still use it. Hence - next evolution
public class ValidationsResult
{
private List<string> _errors = new List<string>(); // private member
public bool IsValid { get => _errors.Count == 0; } // or !Errors.Any()
public string[] Errors { get => _errors.ToArray(); }
public void AddError(string error)
{
_errors.Add(error);
}
}
Now you encapsulating your error collection not letting consumer to modify it directly, but via AddError
As an answer is already posted and accepted, I just want to point to a different thing.
Never implement this type of mechanism in a class! Keep classes as simple as possible.
Please use classes as POCOs, and implement this type of logic in a different layer of the application (e.g. Business Logic layer).
Otherwise, over time, your application will become complex and convoluted and hence hard to maintain.

C# - Implicitly convert or infer generic return type

I've started using the pattern of a generic result type as a wrapper object that includes a return value and information about the operation like whether it succeeded. Here's an example:
public class Researcher
{
public Result<string> LearnThing(bool factDesired)
{
// Validate and bail if failure
var validationResult = ValidateIntentions(factDesired);
if (!validationResult.Succeeded)
{
// Ideally: return validationResult directly without converting to new instance
return Result.Failure<string>(validationResult.Error);
}
return StateOpinion();
}
public Result<string> StateOpinion()
{
return Result.Success("I like turtles");
}
public Result<bool> ValidateIntentions(bool factDesired)
{
if (factDesired)
{
// Ideally: no <bool> required, infer default instead
return Result.Failure<bool>("Only opinions here, sorry");
}
else
{
return Result.Success(true);
}
}
}
public class Result<T>
{
public bool Succeeded { get; set; }
public string Error { get; set; }
public T Value { get; set; }
}
// Static helpers
public static class Result
{
public static Result<T> Success<T>(T value)
{
return new Result<T> { Succeeded = true, Value = value };
}
public static Result<T> Failure<T>(string error)
{
return new Result<T> { Succeeded = false, Error = error };
}
}
Here, the generic Result<T> class is used on each method and a static helper class provides a mechanism to create the results with success status implied. So far, this is working nicely.
The one bikeshedding annoyance I have with this approach is that I need to restate the <T> often where ideally it could be inferred or when I no longer care about T Value (which would be default) and only about Error, as in the case of failures. I somewhat understand that C# doesn't infer from method return types, but I have come across some mentions of implicit operators that seem to allow some cool tricks that I don't quite understand.
So, I humbly submit the question to the C# wizards among you: is there some variation or magic I can add to this approach to achieve more type inference and effectively an implicit Result<"I don't care"> for failure results?
You can use exactly the same technique as described in the article you linked to.
Step 1: You define a non-generic helper class for your Failure case:
public class FailureResult
{
public string Error { get; }
public FailureResult(string error) { Error = error; }
}
Step 2: You change your static helper to return a FailureResult instead of a Result<T>:
public static class Result
{
...
public static FailureResult Failure(string error)
{
return new FailureResult(error);
}
}
Step 3: You define an implicit conversion from FailureResult to Result<T>:
public class Result<T>
{
...
public static implicit operator Result<T>(FailureResult result)
{
return new Result<T> { Succeeded = false, Error = result.Error };
}
}
Step 4: Profit
public Result<bool> ValidateIntentions(bool factDesired)
{
if (factDesired)
{
// No <bool> required!
return Result.Failure("Only opinions here, sorry");
}
else
{
return Result.Success(true);
}
}
(fiddle)
You could get around the bool issue with just an overload:
public static Result<bool> Failure(string error)
{
return new Result<bool> { Succeeded = false, Error = error };
}
Allowing this:
return Result.Failure("Only opinions here, sorry");
As for:
// Ideally: return validationResult directly without converting to new instance
return Result.Failure<string>(validationResult.Error);
You could use an implicit operator:
public static implicit operator Result<string>(Result<T> result)
{
return Result.Failure<string>(result.Error);
}
Which would allow you to do:
if (!validationResult.Succeeded)
{
// Ideally: return validationResult directly without converting to new instance
return validationResult;
}
Though I personally wouldn't do this, it's unexpected and misusing the language feature.
You could however use an instance method or extension method:
public Result<string> AsError()
{
return Result.Failure<string>(Error);
}
In all honesty, I think what you have is declarative and not trying to be magic. I would just stick with some helper (extension) methods if need be.
Maybe something like this:
public class Result<T>
{
public bool Succeeded { get; set; }
public string Error { get; set; }
public T Value { get; set; }
public bool HasValue { get; protected set; } = true;
}
public class Result : Result<object>
{
public Result() { HasValue = false; }
}
public static class ResultFactory
{
public static Result<T> Success<T>(T value)
{
return new Result<T> { Succeeded = true, Value = value };
}
public static Result Success()
{
return new Result { Succeeded = true };
}
public static Result Failure(string error)
{
return new Result { Succeeded = false, Error = error };
}
}
This allows you not to have to "kludge" in a bool somewhere to to make it fit your pattern. Sure you are creating a null object, but that is more-or-less tucked away.

Get Instance using an existing delegate Factory based on Type (or Previous ViewModel)

Based on this page we've created a Wizard that has three steps. Everything works great, but we have one problem with the code given in the link, which is how it creates the next step instance (copy pasted from the link):
protected override IScreen DetermineNextItemToActivate(IList<IScreen> list, int lastIndex)
{
var theScreenThatJustClosed = list[lastIndex] as BaseViewModel;
var state = theScreenThatJustClosed.WorkflowState;
var nextScreenType = TransitionMap.GetNextScreenType(theScreenThatJustClosed);
var nextScreen = Activator.CreateInstance(nextScreenType, state);
return nextScreen as IScreen;
}
Currently, it looks like this in our project:
protected override IWizardScreen DetermineNextItemToActivate(IList<IWizardScreen> list, int lastIndex)
{
var theScreenThatJustClosed = list[lastIndex];
if (theScreenThatJustClosed == null) throw new Exception("Expecting a screen here!");
if (theScreenThatJustClosed.NextTransition == WizardTransition.Done)
{
TryClose(); // Close the entire Wizard
}
var state = theScreenThatJustClosed.WizardAggregateState;
var nextScreenType = _map.GetNextScreenType(theScreenThatJustClosed);
if (nextScreenType == null) return null;
// TODO: CreateInstance requires all constructors for each WizardStep, even if they aren't needed. This should be different!
var nextScreen = Activator.CreateInstance(nextScreenType, state, _applicationService, _wfdRegisterInstellingLookUp,
_adresService, _userService, _documentStore, _windowManager, _fileStore, _fileUploadService, _dialogService,
_eventAggregator, _aanstellingViewModelFactory);
return nextScreen as IWizardScreen;
}
As you can see, we have quite a few parameters we need in some steps. In step 1 we only need like two, but because of the Activator.CreateInstance(nextScreenType, state, ...); we still need to pass all of them.
What I'd like instead is to use a delegate Factory. We use them at more places in our project, and let AutoFac take care of the rest of the parameters. For each of the three steps we only need a delegate Factory that uses the state.
Because all three uses the same delegate Factory with just state, I've placed this Factory in their Base class:
public delegate WizardBaseViewModel<TViewModel> Factory(AggregateState state);
How I'd like to change the DetermineNextItemToActivate method:
protected override IWizardScreen DetermineNextItemToActivate(IList<IWizardScreen> list, int lastIndex)
{
var theScreenThatJustClosed = list[lastIndex];
if (theScreenThatJustClosed == null) throw new Exception("Expecting a screen here!");
if (theScreenThatJustClosed.NextTransition == WizardTransition.Done)
{
TryClose(); // Close the entire Wizard
}
return _map.GetNextScreenFactoryInstance(state);
}
But now I'm stuck at making the GetNextScreenFactoryInstance method:
public IWizardScreen GetNextScreenFactoryInstance(IWizardScreen screenThatClosed)
{
var state = screenThatClosed.WizardAggregateState;
// This is where I'm stuck. How do I get the instance using the Factory, when I only know the previous ViewModel
// ** Half-Pseudocode
var nextType = GetNextScreenType(screenThatClosed);
var viewModelFactory = get delegate factory based on type?;
var invokedInstance = viewModelFactory.Invoke(state);
// **
return invokedInstance as IWizardScreen;
}
Feel free to change the GetNextScreenFactoryInstance any way you'd like. As long as I can get the next Step-ViewModel based on the previous one in the map.
NOTE: Other relevant code, can be found in the link, but I'll post it here as well to keep it all together:
The WizardTransitionMap (only change is it not being a Singleton anymore, so we can instantiate a map outselves):
public class WizardTransitionMap : Dictionary<Type, Dictionary<WizardTransition, Type>>
{
public void Add<TIdentity, TResponse>(WizardTransition transition)
where TIdentity : IScreen
where TResponse : IScreen
{
if (!ContainsKey(typeof(TIdentity)))
{
Add(typeof(TIdentity), new Dictionary<WizardTransition, Type> { { transition, typeof(TResponse) } });
}
else
{
this[typeof(TIdentity)].Add(transition, typeof(TResponse));
}
}
public Type GetNextScreenType(IWizardScreen screenThatClosed)
{
var identity = screenThatClosed.GetType();
var transition = screenThatClosed.NextTransition;
if (!transition.HasValue) return null;
if (!ContainsKey(identity))
{
throw new InvalidOperationException(String.Format("There are no states transitions defined for state {0}", identity));
}
if (!this[identity].ContainsKey(transition.Value))
{
throw new InvalidOperationException(String.Format("There is no response setup for transition {0} from screen {1}", transition, identity));
}
return this[identity][transition.Value];
}
}
Our InitializeMap-method:
protected override void InitializeMap()
{
_map = new WizardTransitionMap();
_map.Add<ScreenOneViewModel, ScreenTwoViewModel>(WizardTransition.Next);
_map.Add<ScreenTwoViewModel, ScreenOneViewModel>(WizardTransition.Previous);
_map.Add<ScreenTwoViewModel, ScreenThreeViewModel>(WizardTransition.Next);
_map.Add<ScreenThreeViewModel, ScreenTwoViewModel>(WizardTransition.Previous);
_map.Add<ScreenThreeViewModel, ScreenThreeViewModel>(WizardTransition.Done);
}
We've changed the code:
The WizardTransitionMap now accepts Delegates. Also, instead of retrieving the type by the WizardTransition-enum value (Next, Previous, etc.), we now retrieve the Factory-invoke based on the next Type (so the inner Dictionary is reversed). So, this is our current WizardTransitionMap:
using System;
using System.Collections.Generic;
namespace NatWa.MidOffice.CustomControls.Wizard
{
public class WizardTransitionMap : Dictionary<Type, Dictionary<Type, Delegate>>
{
public void Add<TCurrentScreenType, TNextScreenType>(Delegate delegateFactory)
{
if (!ContainsKey(typeof(TCurrentScreenType)))
{
Add(typeof(TCurrentScreenType), new Dictionary<Type, Delegate> { { typeof(TNextScreenType), delegateFactory } });
}
else
{
this[typeof(TCurrentScreenType)].Add(typeof(TNextScreenType), delegateFactory);
}
}
public IWizardScreen GetNextScreen(IWizardScreen screenThatClosed)
{
var identity = screenThatClosed.GetType();
var state = screenThatClosed.State;
var transition = screenThatClosed.NextScreenType;
if (!ContainsKey(identity))
{
throw new InvalidOperationException(String.Format("There are no states transitions defined for state {0}", identity));
}
if (!this[identity].ContainsKey(transition))
{
throw new InvalidOperationException(String.Format("There is no response setup for transition {0} from screen {1}", transition, identity));
}
if (this[identity][transition] == null)
return null;
return (IWizardScreen)this[identity][transition].DynamicInvoke(state);
}
}
}
Our InitializeMap is now changed to this:
protected override void InitializeMap()
{
_map = new WizardTransitionMap();
_map.Add<ScreenOneViewModel, ScreenTwoViewModel>(_screenTwoFactory);
_map.Add<ScreenTwoViewModel, ScreenOneViewModel>(_screenOneFactory);
_map.Add<ScreenTwoViewModel, ScreenThreeViewModel>(_screenThreeFactory);
_map.Add<ScreenThreeViewModel, ScreenTwoViewModel>(_screenTwoFactory);
_map.Add<ScreenThreeViewModel, ScreenThreeViewModel>(null);
}
And our DetemineNexttemToActivate method to this:
protected override IWizardScreen DetermineNextItemToActivate(IList<IWizardScreen> list, int previousIndex)
{
var theScreenThatJustClosed = list[previousIndex];
if (theScreenThatJustClosed == null) throw new Exception("Expecting a screen here!");
var nextScreen = _map.GetNextScreen(theScreenThatJustClosed);
if (nextScreen == null)
{
TryClose();
return ActiveItem; // Can't return null here, because Caliburn's Conductor will automatically get into this method again with a retry
}
return nextScreen;
}
We also removed our entire WizardBaseViewModel and just let every Step-ViewModel implement the IWizardScreen:
public interface IWizardScreen : IScreen
{
AggregateState State { get; }
Type NextScreenType { get; }
void Next();
void Previous();
}
With the following implementation in our ScreenOneViewModel:
public AggregateState State { get { return _state; } }
public Type NextScreenType { get; private set; }
public void Next()
{
if (!IsValid()) return;
NextScreenType = typeof(ScreenTwoViewModel);
TryClose();
}
public void Previous()
{
throw new NotImplementedException(); // Isn't needed in first screen, because we have no previous
}
And the following implementation in our ScreenThreeViewModel:
public AggregateState State { get { return _state; } }
public Type NextScreenType { get; private set; }
public void Next()
{
NextScreenType = typeof(ScreenThreeViewModel); // Own type, because we have no next
TryClose();
}
public void Previous()
{
NextScreenType = typeof(ScreenTwoViewModel);
TryClose();
}
And each Step-ViewModel has its own delegate Factory, like this one for ScreenTwoViewModel:
public delegate ScreenTwoViewModel Factory(AggregateState state);

Error Reporting

I have a class that follows the Command Pattern.
It has 2 methods which are Execute, and CanExecute which checks whether to invoke Execute or not (they derive from ICommand).
CanExecute invokes a few methods that check that all required services are running, the version is correct, etc.
After CanExecute is invoked, it may fail and return false and I need to know why. Is it because of a bad version, services, missing file, etc.
What is the best strategy to know what is the problem
One option is whenever a required condition fails I can throw an exception that will describe the error in the message field. However the possibility that it will fail is expected and you shouldn't use exceptions for regular flow of control. So I'm really not sure.
Thank you.
You can use a collection of "reasons" that will tell the users of the class why CanExecute returned false. The reasons can be a simple IEnumerable<string>.
public bool CanExecute() {
var messages = new List<string>();
if (!Condition1) {
messages.Add("Missing Condition1");
}
...
Messages = messages;
return messages.Count == 0;
}
public IEnumerable<string> Messages { get; private set; }
Then, client code can show the collection of messages to end-users.
UPDATE:
You can also associate new commands with the messages to give the users ways to fix the problems found. In this case, instead of an IEnumerable<string>, you can create your own class that encapsulates that information:
public class Message {
public string Text { get; set; }
public ICommand Command { get; set; }
}
...
public bool CanExecute() {
var messages = new List<Message>();
if (!Condition1) {
messages.Add(
new Message {
Text = "Missing Condition1",
Command = new FixCondition1Command()
}
);
}
...
Messages = messages;
return messages.Count == 0;
}
public IEnumerable<Message> Messages { get; private set; }
UPDATE: Reworked based on feedback.
Since the UI needs the reasons CanExecute() returns false, two things come to mind:
Option 1: Add an enumerable message property to the command interface and populate it as needed during the call to CanExecute(). The UI could then interrogate the property as needed. If you go this route, make sure you clear out the contents of the property each call to CanExecute() so you don't lose track of state.
public interface ICommand
{
IEnumerable<string> Messages { get; }
bool CanExecute();
void Execute();
}
public class SomeCommand : ICommand
{
public IEnumerable<string> Messages { get; private set; }
public bool CanExecute()
{
var messages = new List<string>();
var canExecute = true;
if (SomeCondition)
{
canExecute = false;
messages.Add("Some reason");
}
if (AnotherCondition)
{
canExecute = false;
messages.Add("Another reason");
}
Messages = messages;
return canExecute;
}
public void Execute() { }
}
Option 2: Have CanExecute() return an object which contains the bool as well as an enumerable messages property. This makes it obvious that the messages only apply to that call of CanExecute(). However, depending on where/how you're implementing (e.g. data binding), this could complicate other scenarios more than you're looking for.
public class CanExecuteResult
{
public bool CanExecute { get; set; }
public IEnumerable<string> Messages { get; set; }
}
public interface ICommand
{
CanExecuteResult CanExecute();
void Execute();
}
public class SomeCommand : ICommand
{
public CanExecuteResult CanExecute()
{
var result = new CanExecuteResult { CanExecute = true };
var messages = new List<string>();
if (SomeCondition)
{
result.CanExecute = false;
messages.Add("Some reason");
}
if (AnotherCondition)
{
result.CanExecute = false;
messages.Add("Another reason");
}
result.Messages = messages;
return result;
}
public void Execute() { }
}
Obviously, the specifics of how you want to handle the interfaces, enumerable types, etc. is up to you. The code is just a representation of the idea.
Bool CanExecute()
{
if(!CheckXXX)
throw new Exception("CheckXXX function throws an exception")
if(!CheckYYY)
throw new Exception("CheckYYY function throws an exception")
if(!CheckZZZ)
throw new Exception("CheckZZZ function throws an exception")
return true; //everything is working fine
}

Encapsulating Action<T> and Func<T>?

I'm trying to make a design for some sort of IExecutable interface. I will not get into details, but the point is that I have several Actions that need to be executed from a base class. They may take different parameters (no big deal), and they may/may not return a value.
So far, this is my design:
public abstract class ActionBase
{
// ... snip ...
}
public abstract class ActionWithResultBase<T>: ActionBase
{
public abstract T Execute();
}
public abstract class ActionWithoutResultBase: ActionBase
{
public abstract void Execute();
}
So far, each of my concrete actions need to be a child from either ActionWithResultBase or ActionWithoutResult base, but I really don't like that. If I could move the definition of Execute to ActionBase, considering that the concrete class may or may not return a value, I will have achieved my goal.
Someone told me this could be done with using Func and Action, for which I totally agree, but I can't find a way to have that into one single class so that the caller would know if the action is going to return a value or not.
Brief: I want to do something like:
// Action1.Execute() returns something.
var a = new Action1();
var result = a.Execute();
// Action2.Execute() returns nothing.
var b = new Action2();
b.Execute();
If you want a lightweight solution, then the easiest option would be to write two concrete classes. One will contain a property of type Action and the other a property of type Func<T>:
public class ActionWithResult<T> : ActionBase {
public Func<T> Action { get; set; }
}
public class ActionWithoutResult : ActionBase {
public Action Action { get; set; }
}
Then you can construct the two types like this:
var a1 = new ActionWithResult<int> {
CanExecute = true,
Action = () => {
Console.WriteLine("hello!");
return 10;
}
}
If you don't want to make Action property read/write, then you could pass the action delegate as an argument to the constructor and make the property readonly.
The fact that C# needs two different delegates to represent functions and actions is quite annoying. One workaround that people use is to define a type Unit that represents "no return value" and use it instead of void. Then your type would be just Func<T> and you could use Func<Unit> instead of Action. The Unit type could look like this:
public class Unit {
public static Unit Value { get { return null; } }
}
To create a Func<Unit> value, you'll write:
Func<Unit> f = () => { /* ... */ return Unit.Value; }
The following interfaces should do the trick -- it's essentially copying the Nullable pattern
public interface IActionBase
{
bool HasResult { get; }
void Execute() { }
object Result { get; }
}
public interface IActionBase<T> : IActionBase
{
new T Result { get; }
}
public sealed class ActionWithReturnValue<T> : IActionBase<T>
{
public ActionWithReturnValue(Func<T> action) { _action = action; }
private Func<T> _action;
public bool HasResult { get; private set; }
object IActionBase.Result { get { return this.Result; } }
public T Result { get; private set; }
public void Execute()
{
HasResult = false;
Result = default(T);
try
{
Result = _action();
HasResult = true;
}
catch
{
HasResult = false;
Result = default(T);
}
}
}
public sealed class ActionWithoutReturnValue : IActionBase
{
public bool HasResult { get { return false; } }
object IActionBase.Result { get { return null; } }
public void Execute() { //... }
}
You know that you can ignore the return value of a method right? You don't have to use it.
what about something simple:
public class ActionExecuter
{
private MulticastDelegate del;
public ActionExecuter(MulticastDelegate del)
{
this.del = del;
}
public object Execute(params object[] p)
{
return del.DynamicInvoke(p);
}
}

Categories

Resources