0

We are working on plugin for ReSharper and we want to make our plugin extensible. Seems, we should use ShellComponent attribute to do it but we can not find any examples. Could anybody enplane how to define custom extension point and how to manage extension. Example of code of extension point and extension implementation would be very helpful.

Thanks.

gsv
  • 277
  • 1
  • 9

1 Answers1

1

If you're looking to write a plugin that can extend ReSharper, you need to tell ReSharper about the classes in your plugin, by marking them with the [ShellComponent] or [SoutionComponent] attributes. These attributes have different lifetimes - a shell component lasts the lifetime of ReSharper itself, and a solution component is created when a solution is opened and disposed when the solution is closed.

To make ReSharper do something useful with your components, they typically have to implement an interface, such as ICodeCompletionItemsProvider, and sometimes have to use a different attribute, such as [CodeCleanupModule] (which itself derives from ShellComponentAttribute). There are many extension points in ReSharper, and the one that's appropriate for you depends on what you're trying to do - refactoring, unit test provider, code cleanup, code completion items, etc. The devguide provides a good introduction to the more common extension points.

But if you want to make your own plugin extensible, then your component needs to work with a kind of provider pattern, by deferring work to multiple provider instances. For example, code cleanup works by deferring to multiple code cleanup modules, each responsible for cleaning up a different aspect of your code (whitespace, ordering, etc). To do this, your component should take in a collection of providers in the constructor. ReSharper's component model will automatically create a collection of these types and pass them to. More specifically, you should have a constructor that takes an IEnumerable<T> or IViewable<T>, where T is the interface of the provider you're going to define and call. The IEnumerable<T> will give you a simple collection of providers, but IViewable<T> represents an observable collection, and allows you to subscribe to notifications of new providers being made available from the component model.

citizenmatt
  • 18,085
  • 5
  • 55
  • 60
  • Hi citizenmatt Thanks for an answer. We want to make our plugin extensible. Could you please provide more details. How we should to define extension point in our point and how we should define extensions for it. Let we want to describe MyExtensionPoint. It should has constructor that takes IViewable Should it be marked with any attribute? Next, when we define extension, it should implement IMyExtension. Should extension be marked with attribute? – gsv Sep 11 '14 at 08:52
  • Yep. Exactly that. ReSharper composes all types marked with `[ShellComponent]` or `[SolutionComponent]`. If you have a constructor parameter with `IViewable`, it will find *all* components that implement `T`, and give them to you. So your `T` class must be marked as a component, and `T` should just be a common interface that anyone can implement. – citizenmatt Sep 11 '14 at 13:08