سؤال

Is it possible to use Resharper to refactor code such that the below method Eat is extracted into a seperate class, and the newly extracted class is injected in the Dinner class as an external dependency?

Original Code

public class Dinner
{
    public Dinner()
    {

    }

    public void Eat()
    {
        //do the eating
    }
}

Refactored Code

public interface IEatService
{
    void Eat();
}

public class EatService : IEatService
{
    public void Eat()
    {

    }
}
public class Dinner
{
    private readonly IEatService _eatService = null;

    public Dinner(IEatService eatService)
    {
        _eatService = eatService;
    }

    public void Eat()
    {
        _eatService.Eat();
    }

}

It doesn't have to be exactly as the refactored code - this is shown to give an idea.

هل كانت مفيدة؟

المحلول

You can do it nearly as you want in R# 7 using three-step refactoring:

  1. Place the caret at your Eat method, invoke Extract Class refactoring (Ctrl-Shift-R in VS), name your class EatService.
  2. Place the caret at your EatService class, invoke Extract Interface refactoring.
  3. Place the caret at your EatService class, invoke Use Base type Where Possible refactoring.

All that is left is to fix a constructor in Dinner class so it would get IEatService as a parameter.

نصائح أخرى

Using R# 6, one way to achieve this would be with this sequence of operations. Note that refactorings are available on both ReSharper | Refactor on the menu bar, or (quicker) in context with Ctrl+Shift+R. There's still a bit of typing; I wouldn't be surprised if there were a way that didn't require you to type anything at all.

  • Start with your Original Code in a file named Dinner.cs
  • With the cursor on Eat, user the Extract Interface refactoring, naming the interface IEatService
  • With the cursor on IEatService, Alt+Enter and create a derived type, accepting the offered name of EatService, and Alt+Enter to fill in the method implementation body
  • Here's where we have to type: In Dinner.Eat(), type _eatService.Eat();. Note that _eatService is red; Alt+Enter on it, choose 'Create field', change the offered type to IEatService
  • With the cursor on the definition of _eatService, Alt+Enter and choose 'Initialize from ctor paramater, and then Alt+Enter again and accept the readonly suggestion

Note that initialising _eatService to null is redundant; R# would let you know this.

We're now at your target code.

I think R# 7 has some new refactorings (such as Extract Class) which might make this quicker.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top