15

I'm using RX extensions and WF4 to create a workflow which reacts to observable messages to progress the workflow. To do this, I bring in an object containing an IObservable (ModuleMessage being my abstract class.) The problem I'm having is that .Subscribe fails to recognize any of its extension methods, namely the one for lambda extpressions/method groups. In the following code, I have references:

using System.Activities;
using System.Activities.Hosting;
using System.Collections.Generic;
using System.Reactive.Linq;

And also the following line of code:

    internal void AddModuleCallback(IModule module)
    {
        if (!addedCallback)
        {
            addedCallback = true;
            module.Messages.Where(m => m is MemberLeftModuleMessage || m is MemberRemovedModuleMessage).Subscribe(m => this.OnMemberExit(m)); // This line errors
        }
    }

    internal void OnMemberExit(ModuleMessage message)
    {
        // Gizmo was fired, resume the bookmark
        this.instance.BeginResumeBookmark(
            new Bookmark(ModuleVisit.BookmarkName),
            message is MemberLeftModuleMessage,
            r => this.instance.EndResumeBookmark(r),
            null);
    }

With the compile-time error of:

Error   1   Cannot convert lambda expression to type 'System.IObserver<Components.Messages.ModuleMessage>' because it is not a delegate type    <Removed>\WaitForModuleVisitExtension.cs    34  119 Components

Please note, this code is adapted from a sample and has not been factored out to my liking, I'm purely concerned in the problem at hand. I'm no pro with RX or WF4, but have used subscribe in this way elsewhere in the very same solution. I've added RX to this project via NuGet.

Edit: the following error if I use as a method group (instead of lambda):

Error   2   Argument 1: cannot convert from 'method group' to 'System.IObserver<Components.Messages.ModuleMessage>' <removed>\WaitForModuleVisitExtension.cs    34  119 Components
Sprague
  • 1,610
  • 10
  • 22
  • Can you share a link to the sample you mentioned? This looks quite interesting. I always thought Observables were not serializable, so how can you use them inside a workflow which needs support for persistence at any point in time? – julealgon Apr 16 '14 at 13:33
  • This was so long ago, I can't even remember. I think I never got to that point before being distracted by something else shiny (this was a personal project) – Sprague Jun 11 '14 at 09:47

1 Answers1

31

You're missing this:

using System;

That's the namespace containing the ObservableExtensions static class with all the Subscribe extension methods.

Extension methods are "discovered" via using directives (as well as the namespace hierarchy of the code trying to use them).

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    Thanks! This is not obvious... I wish there was a better error. I suppose that's the price we pay for extension methods =( I'm using ReSharper, usually it catches these things for me. It must be the existence of another .Subscribe which is preventing the discovery. – Sprague May 09 '12 at 17:24
  • It's a completely non-obvious problem. Subscribe taking IObserver is the one that Visual Studio will detect. So the extension methods won't be picked up. – Ray Booysen May 09 '12 at 18:53
  • 3
    Unfortunately, this problem seems to hurt those of us who remove un-needed namespaces the most! Too bad... – Sprague Jul 08 '13 at 14:25
  • 1
    Don't forget you need a reference to System.Reactive.Core as well, to make the extension method discoverable – Dr. Andrew Burnett-Thompson Jan 09 '14 at 16:12
  • 1
    @Sprague ctrl+alt+space, Resharper will try to resolve all valid extension methods in all the referenced assemblies regardless of whether you are already using the namespace. – Slugart Feb 13 '14 at 12:21
  • @Slugart thanks. Usually, I use alt-enter and then select the namespace option, this will be easier. In this case, I didn't know exactly what was wrong or missing, so even that may not have helped. I think this is just intrinsic to extension methods. More accurately, the type system makes exploring an API really cool, so cool that you forget the old way of finding things :D – Sprague Feb 14 '14 at 13:39
  • This is part of the `System` namespace? Why?! – James Wright Feb 16 '15 at 17:56