Caliburn.Micro and a WebServiceResult

Oct 22, 2010 at 4:06 PM
Edited Oct 22, 2010 at 5:56 PM

I'm looking for the correct version of this class for Caliburn.Micro

WebServiceResult

The above class is from the ContactManager example in the full Caliburn framework. It does not cut and paste directly into a Micro-based project. There are too many missing classes to use this directly. Thoughts? or anyone know of the best replacement?

Oct 23, 2010 at 10:15 AM

Event though the underlying infrastructure is very different in Caliburn Micro (which is based on System.Windows.Interactivity), the concepts are pretty much the same.

Here is the CM version:

public class WebServiceResult<T, K> : IResult
    where T : new()
    where K : EventArgs
{

    readonly static Func<bool> ALWAYS_FALSE_GUARD= () => false;
    readonly static Func<bool> ALWAYS_TRUE_GUARD = () => true;

    private readonly Action<K> _callback;
    private readonly Expression<Action<T>> _serviceCall;

    private ActionExecutionContext _currentContext;
    private Func<bool> _originalGuard;




    public WebServiceResult(Expression<Action<T>> serviceCall)
    { 
        _serviceCall = serviceCall;
    }

    public WebServiceResult(Expression<Action<T>> serviceCall, Action<K> callback)
    {
        _serviceCall = serviceCall;
        _callback = callback;
    }

    public event EventHandler<ResultCompletionEventArgs> Completed = delegate { };

    public void Execute(ActionExecutionContext context)
    {
        _currentContext = context;

        //if you would to disable the control that caused the service to be called, you could do this:
        ChangeAvailability(false);

        var lambda = (LambdaExpression)_serviceCall;
        var methodCall = (MethodCallExpression)lambda.Body;
        var eventName = methodCall.Method.Name.Replace("Async", "Completed");
        var eventInfo = typeof(T).GetEvent(eventName);

        var service = new T();

        eventInfo.AddEventHandler(service, new EventHandler<K>(OnEvent));

        _serviceCall.Compile()(service);
    }

    public void OnEvent(object sender, K args)
    {
        //re-enable the control that caused the service to be called:
        ChangeAvailability(true);

        if (_callback != null)
            _callback(args);

        Completed(this, new ResultCompletionEventArgs());
    }



    private void ChangeAvailability(bool isAvailable)
    {
        if (_currentContext == null) return;

        if (!isAvailable) {
            _originalGuard = _currentContext.CanExecute;
            _currentContext.CanExecute = ALWAYS_FALSE_GUARD;
        }
        else if (_currentContext.CanExecute == ALWAYS_FALSE_GUARD) {

            _currentContext.CanExecute = _originalGuard ?? ALWAYS_TRUE_GUARD;
        }


        _currentContext.Message.UpdateAvailability();

    }


}