Search code examples
c#wpfmvvmmyo

How to extract connection code to a method? WPF


I'm porting my application over to an MVVM pattern and have started by moving code from the code behind of my view to it's own model class.

The first step I have taken is moving the networking code for the device, https://www.thalmic.com/en/myo/ to a MyoDevice class.

The original code hosted all of the networking code in the code behind for the view which I'm told is bad practice.

I've tried using the "Extract to Method" tool in Visual Studio but I keep getting the error: "The selected text is not inside a method"

Does anyone know how I can extract this connection and disconnection code into two separate methods?

Originally the class looked like this before moving the device connection code to it's own model:

http://hastebin.com/gepudayele.cs

This is the code after it's placed in the MyoDevice Model:

http://hastebin.com/ocogoseziy.cs

The code for example for the connection and disconnection, to listen for the device when it connects/looses connection:

// create a hub that will manage Myo devices for us
        channel = Channel.Create(ChannelDriver.Create(ChannelBridge.Create()));
        hub = Hub.Create(channel);
        {

            // listen for when the Myo connects
            hub.MyoConnected += (sender, e) =>
            {

                this.Dispatcher.Invoke((Action)(() =>
                {
                    statusTbx.Text = "Myo has connected! " + e.Myo.Handle;
                    e.Myo.Vibrate(VibrationType.Short);

                    // unlock the Myo so that it doesn't keep locking between our poses
                    e.Myo.Unlock(UnlockType.Hold);

                    e.Myo.PoseChanged += Myo_PoseChanged;

                    e.Myo.OrientationDataAcquired += Myo_OrientationDataAcquired;



                }));
            };

            // listen for when the Myo disconnects
            hub.MyoDisconnected += (sender, e) =>
            {
                this.Dispatcher.Invoke((Action)(() =>
                {
                    statusTbx.Text = "Myo has disconnected!";
                    e.Myo.Vibrate(VibrationType.Medium);
                    e.Myo.OrientationDataAcquired -= Myo_OrientationDataAcquired;
                    e.Myo.PoseChanged -= Myo_PoseChanged;


                }));
            };

            // start listening for Myo data
            channel.StartListening();
        }

Solution

  • There's nothing special about what you are doing, the automated tool should work. But tools break, so if it just isn't working, I would do it manually.

    The steps to refactor code into a method are pretty simple:

    1. Declare a method. If it doesn't have an obvious return type, just use void for now. No parameters yet.
    2. Cut-Paste the code to be refactored from the old code into this method
    3. Any variables that are immediately initialized (but not declared) declare inside the method.
    4. Any variables that are simply used, but clearly weren't set up/initialized by the method need to become parameters
    5. If you discover you need a return value, add it in.
    6. Build!
    7. Discover things you missed, declare or add parameters as necessary (following above guidelines)
    8. Have the original code that had the removed section invoke this method instead.

    Obviously this gets easier with experience. I would strongly reccommend practicing doing this as much as possible, and refrain from using the auto-refactoring tool until you understand what it's doing for you. Tools break. People don't (at least not in the same way).