├── Readme.md
├── SDK
├── Readme.md
├── articles
│ ├── APILinks.md
│ ├── AddingCustomContextMenu.md
│ ├── AdvancedSeries.md
│ ├── ConnectedServiceProviderAuthorMockups.pptx
│ ├── ConnectedServicesExtensibilityApiContracts.docx
│ ├── ConnectedServicesExtensibilityApiContracts.md
│ ├── ConnectedServicesOverview.docx
│ ├── ConnectedServicesOverview.md
│ ├── ConnectedServicesPrinciples.docx
│ ├── ConnectedServicesPrinciples.md
│ ├── ConnectedServicesSDKChangesRCtoRTM.md
│ ├── CreatingAConnectedServiceExtension.md
│ ├── DosAndDonts.md
│ ├── ExtensionIcon.md
│ ├── GettingStartedSeries.md
│ ├── ModifyingWPFStyles.md
│ ├── PrerequisiteComponents.md
│ ├── SupportingConnectedServicesAcrossMultipleProjects.md
│ ├── TroubleshootingConnectedServiceExtensions.docx
│ ├── TroubleshootingConnectedServiceExtensions.md
│ └── media
│ │ ├── ConnectedServiceSelectionDialog.png
│ │ ├── ConnectedServicesOverview
│ │ └── AddConnSvcContextMenu.jpg
│ │ ├── CreatingAConnectedServiceExtension
│ │ ├── AddConnectedServiceSample.jpg
│ │ ├── AddConnectedServiceSample.png
│ │ ├── AddNewAsset.jpg
│ │ ├── AddNewDependency.jpg
│ │ ├── AddNewDependency.png
│ │ ├── AddSdkNuGet.jpg
│ │ ├── AddSdkNuGet.png
│ │ ├── CreateNewVsixProject.jpg
│ │ ├── CreateNewVsixProject.png
│ │ ├── GridConfiguratorWithCallouts.jpg
│ │ ├── GridConfiguratorWithCallouts.png
│ │ ├── Progress.jpg
│ │ ├── Progress.png
│ │ ├── ProviderInstanceHandler.jpg
│ │ ├── ProviderInstanceHandler.png
│ │ ├── SetExpDebugging.jpg
│ │ ├── SetExpDebugging.png
│ │ ├── SinglePageConfiguratorView.jpg
│ │ ├── SinglePageConfiguratorView.png
│ │ ├── SinglePageConfiguratorWithCallouts.jpg
│ │ ├── SinglePageConfiguratorWithCallouts.png
│ │ ├── SolExpMyServiceFolder.jpg
│ │ ├── SolExpMyServiceFolder.png
│ │ ├── SolExpViewViewModelFoldres.jpg
│ │ ├── SolExpViewViewModelFoldres.png
│ │ ├── VsixProjectProperties.jpg
│ │ ├── VsixProjectProperties.png
│ │ ├── WizardConfiguratorWithCallouts.jpg
│ │ └── WizardConfiguratorWithCallouts.png
│ │ ├── ExtensionIcon
│ │ ├── AllVsixIconsSet.jpg
│ │ ├── ExtenionIconProperties.jpg
│ │ ├── ExtensionsAndUpdatesMissingIcons.jpg
│ │ ├── ExtensionsAndUpdatesMissingIcons.png
│ │ └── vsmanifestMetadata.jpg
│ │ ├── HandlerClassDiagram.png
│ │ ├── ProviderClassDiagram.png
│ │ └── SalesforceConfiguration.png
└── media
│ ├── CloudConnectedServices_32x.png
│ ├── ConnectedServicesContracts.png
│ ├── Grid.jpg
│ ├── SInglePage.jpg
│ ├── SelectionUi.jpg
│ └── Wizard.jpg
├── articles
├── Readme.md
└── media
│ └── placeholder.png
└── media
├── Channel9ConnectedServices.jpg
├── Channel9Logo.png
├── CloudConnectedServices_32x.png
├── ConnectedServiceProviderSelection.jpg
├── ConnectedServicesBuild2015.jpg
├── ConnectedServicesOnDemand.jpg
└── VSToolboxConnectedServices(100).jpg
/Readme.md:
--------------------------------------------------------------------------------
1 | # Connected Services 
2 |
3 | ### Videos of Connected Service usage
4 |
5 | 
6 |
7 | [An overview of Connected Services on Channel 9](http://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Connected-Services)
8 |
9 | 
10 |
11 | [A 7 minute demo of Connected Services showing Visual Studio Online, Salesforce, security the site with Azure Active Directory and analytics with App Insights](https://channel9.msdn.com/Series/Visual-Studio-2015-Enterprise-Videos/Connecting-to-Services-with-Visual-Studio)
12 |
13 | 
14 |
15 | [//build 2015: On the Shoulders of Giants: Building Apps that Consume Modern SaaS Endpoints with Visual Studio 2015](https://channel9.msdn.com/Events/Build/2015/3-759)
16 |
17 | ### Microsoft Connected Services
18 | * [Azure Active Directory](http://go.microsoft.com/fwlink/?LinkId=513809)
19 | * [Office 365]( http://go.microsoft.com/fwlink/?LinkID=512158)
20 | * [Azure Storage](http://go.microsoft.com/fwlink/?LinkId=513126)
21 | * [Azure Mobile Services](http://azure.microsoft.com/en-us/services/app-service/mobile/)
22 | * [Application Insights](http://go.microsoft.com/fwlink/?LinkID=511987)
23 |
24 | ### Partner Connected Service
25 | * [Salesforce](https://visualstudiogallery.msdn.microsoft.com/site/search?f%5B0%5D.Type=SearchText&f%5B0%5D.Value=salesforce&f%5B1%5D.Type=User&f%5B1%5D.Value=Salesforce%20Developer%20Program&f%5B1%5D.Text=Salesforce%20Developer%20Program)
26 | * [Datalogics](http://www.datalogics.com/ConnectedService)
27 |
28 | ### Building Connected Services
29 | For information on how to build a Connected Service: [Connected Services SDK](https://github.com/Microsoft/ConnectedServices/tree/master/SDK)
30 |
31 | ### Providing Feedback
32 | We value your feedback as we build out the Connected Services ecosystem and SDK. You can provide feedback via:
33 |
34 | * [User Voice](https://visualstudio.uservoice.com/forums/265038-connected-services) for suggestions and issues on the core Connected Services experience in Visual Studio
35 | * [Connected Services SDK Issues](https://github.com/Microsoft/ConnectedServices-ProviderAuthorSamples/issues) for SDK Feedback
36 |
--------------------------------------------------------------------------------
/SDK/Readme.md:
--------------------------------------------------------------------------------
1 | # Connected Services 
2 |
3 | ### Welcome to the Visual Studio Connected Services SDK
4 |
5 |
6 | Here you'll find information for building your own Connected Services for configuration within Visual Studio 2015.
7 |
8 | ## Getting Started
9 | Here you'll find articles, resources and samples for getting started.
10 |
11 | ## Late Breaking Announcements
12 | - The [Connected Services SDK 2.0](http://www.nuget.org/packages/Microsoft.VisualStudio.ConnectedServices/) released version is now available on NuGet
13 | - [A list of RC to RTM/Release SDK changes](./articles/ConnectedServicesSDKChangesRCtoRTM.md) are now available
14 |
15 | ## Articles
16 | - [Principles for building a Connected Service](./articles/ConnectedServicesPrinciples.md) Describes the principles for building a Connected Service, such as scaffolding code vs. generating, and other aspects that will provide guidance on the experiences targeted with Connected Services
17 | - [Getting Started](./articles/GettingStartedSeries.md) - the Hello World for authoring Connected Services
18 | - [Advanced Topics](./articles/AdvancedSeries.md) - reference topics for authoring Connected Services
19 |
20 |
21 | ## Resources
22 | - [PowerPoint template for mocking up your Connected Service provider](./articles/ConnectedServiceProviderAuthorMockups.pptx) Mock up your provider before you start building it
23 | - [Extensibility APIs](./articles/ConnectedServicesExtensibilityApiContracts.md) This document describes the extensibility APIs that are available to extend the Connected Services experience in Microsoft Visual Studio 2015 RC.
24 | - [Connected Service SDK Reference APIs](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.aspx) Class, Property, Event and Method definitions
25 | - [Samples for building Connected Services GitHub Repo](https://github.com/Microsoft/ConnectedServicesSdkSamples) A set of samples, such as using different configurators (Grid, SinglePage and Wizard), Auth, Config, and more to come...
26 | - [Connected Services SDK NuGet](https://www.nuget.org/packages/Microsoft.VisualStudio.ConnectedServices/) SDK binaries for building a Connected Service
27 |
28 | ### Partner Connected Service Providers
29 | Here are some open source providers being built by our partners
30 |
31 | * [Salesforce](https://visualstudiogallery.msdn.microsoft.com/site/search?f%5B0%5D.Type=SearchText&f%5B0%5D.Value=salesforce&f%5B1%5D.Type=User&f%5B1%5D.Value=Salesforce%20Developer%20Program&f%5B1%5D.Text=Salesforce%20Developer%20Program)
32 | * [Datalogics](http://www.datalogics.com/products/pdf/pdfwebapi/)
33 |
34 | ### Providing Feedback
35 | We value your feedback as we build out the Connected Services ecosystem and SDK. You can provide feedback via:
36 |
37 | * [User Voice](https://visualstudio.uservoice.com/forums/265038-connected-services) for suggestions and issues on the core Connected Services experience in Visual Studio
38 | * [Connected Services SDK Issues](https://github.com/Microsoft/ConnectedServices-ProviderAuthorSamples/issues) for SDK Feedback
39 | [ConnectedServiceLogo]: ./media/CloudConnectedServices_32x.png
40 |
41 |
--------------------------------------------------------------------------------
/SDK/articles/APILinks.md:
--------------------------------------------------------------------------------
1 | [handler]: https://msdn.microsoft.com/library/microsoft.visualstudio.connectedservices.connectedservicehandler.aspx
2 | [configurator]: https://msdn.microsoft.com/library/microsoft.visualstudio.connectedservices.connectedserviceconfigurator.aspx
3 | [handlerexportattribute]: https://msdn.microsoft.com/library/microsoft.visualstudio.connectedservices.connectedservicehandlerexportattribute.aspx
4 | [providerid]: https://msdn.microsoft.com/library/microsoft.visualstudio.connectedservices.connectedserviceproviderexportattribute.providerid.aspx
5 |
6 |
--------------------------------------------------------------------------------
/SDK/articles/AddingCustomContextMenu.md:
--------------------------------------------------------------------------------
1 | # Adding custom context menu to provider folder node
2 |
3 | ## Service provider logic
4 | 1. Providing a custom context menu is optional.
5 | 2. Service providers can register their custom context commands with VS by using a VSCT file. Through their VSCT file the providers will control grouping of their commands and their relative positions in the context menu. They will parent their command groups under guid="guidSHLMainMenu" id="IDM_VS_CTXT_FOLDERNODE" which are well-known values. The visibility of these commands will be constrained based on a custom UIContext unique to that provider.
6 | Note that this is all standard Visual Studio command authoring code and nothing Connected Services specific.
7 | 3. Service providers will use a predetermined guid based on the provider id as their UIContext guid. Note: generating this predetermined guid is something that the provider author will do offline and only once per each provider id. Once generated they can hardcode that guid in their code.
8 |
9 | ## Getting UIContextGuidFromProviderId
10 | Steps to generate UIContext guid based on the provider id string:
11 | 1. Get a byte array representing the UTF8 encoding of the provider id string. This is the same provider id string that a provider specifies in the exisiting ConnectedServiceProviderExport attribute.
12 | 2. Generate a SHA256 hash of this byte array.
13 | 3. Use the most significant 16 bytes to generate a guid.
14 |
15 | ### C# code snippet to get UIContext guid from a given provider id
16 | ```c#
17 | static Guid GetUIContextGuidFromProviderId(string providerId)
18 | {
19 | byte[] bytes = Encoding.UTF8.GetBytes(providerId);
20 |
21 | SHA256 mySHA256 = SHA256Managed.Create();
22 | byte[] hashValue = mySHA256.ComputeHash(bytes);
23 |
24 | return new Guid(hashValue.Take(16).ToArray());
25 | }
26 | ```
27 | ### Powershell script to get UIContext guid from a given provider id
28 | ```powershell
29 | function GetUIContextGuidFromProviderId([string]$providerId)
30 | {
31 | $toHash = [System.Text.Encoding]::UTF8.GetBytes($providerId)
32 | $hasher = new-object System.Security.Cryptography.SHA256Managed
33 | $hashByteArray = $hasher.ComputeHash($toHash)
34 |
35 | $hashByteArray = $hashByteArray[0..15]
36 |
37 | [UInt32]$a = [Convert]::ToUInt32(([Convert]::ToUInt32($hashByteArray[3]) -shl 24) -bor ([Convert]::ToUInt32($hashByteArray[2]) -shl 16) -bor ([Convert]::ToUInt32($hashByteArray[1]) -shl 8) -bor ($hashByteArray[0]))
38 | [UInt16]$b = [Convert]::ToUInt16(([Convert]::ToUInt32($hashByteArray[5]) -shl 8) -bor ($hashByteArray[4]))
39 | [UInt16]$c = [Convert]::ToUInt16(([Convert]::ToUInt32($hashByteArray[7]) -shl 8) -bor ($hashByteArray[6]))
40 |
41 | [Byte]$d = $hashByteArray[8]
42 | [Byte]$e = $hashByteArray[9]
43 | [Byte]$f = $hashByteArray[10]
44 | [Byte]$g = $hashByteArray[11]
45 | [Byte]$h = $hashByteArray[12]
46 | [Byte]$i = $hashByteArray[13]
47 | [Byte]$j = $hashByteArray[14]
48 | [Byte]$k = $hashByteArray[15]
49 |
50 | [Guid]$guid = new-object Guid($a, $b, $c, $d, $e, $f, $g, $h, $i, $j, $k)
51 |
52 | return $guid
53 | }
54 | ```
55 |
56 | ## Sample VSCT file
57 | ```xml
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
78 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 | ```
105 |
106 | ## Sample provider package class
107 | ```c#
108 | [PackageRegistration(UseManagedResourcesOnly = true)]
109 | [ProvideMenuResource("menus.ctmenu", 1)]
110 | [ProvideBindingPath]
111 | [Guid(PackageConstants.PackageGuidString)]
112 | // Autoload on ContextMenuUIContextGuid is NOT recommended to ensure package is loaded only when actually needed. However, if a provider wants
113 | // to add some custom logic for command visibility that's in addition to VisibilityConstraints in the vsct file then Autoload on ContextMenuUIContextGuid
114 | // would be needed. For example a provider might want to show a custom context menu only if the selected provider folder node belongs to a C#
115 | // project then it would need to add this additional custom logic in the IOleCommandTarget.QueryStatus as shown below for command
116 | // ConnectedServicesTestContextMenuCsharpCmdId. If such a custom logic is not needed and the VisibilityConstraints in the vsct file is good enough
117 | // then Autoload on ContextMenuUIContextGuid is not needed. For example if this provider only supported commands like ConnectedServicesTestContextMenuCmdId
118 | // then this Autoload would not be needed.
119 | [ProvideAutoLoad(PackageConstants.ContextMenuUIContextGuid_String)]
120 | internal sealed class TestPackage : Package, IOleCommandTarget
121 | {
122 |
123 | #region IOleCommandTarget members
124 |
125 | int IOleCommandTarget.QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
126 | {
127 | if (pguidCmdGroup == PackageConstants.ConnectedServicesTestContextMenuCmdSet)
128 | {
129 | switch (prgCmds[0].cmdID)
130 | {
131 | case PackageConstants.ConnectedServicesTestContextMenuCsharpCmdId:
132 | var uiContext = UIContext.FromUIContextGuid(PackageConstants.ContextMenuUIContextGuid);
133 | if (uiContext != null && uiContext.IsActive && this.DoesCapabilityMatchForCurrentProject("Csharp"))
134 | {
135 | prgCmds[0].cmdf = (uint)(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED);
136 | }
137 | else
138 | {
139 | prgCmds[0].cmdf = (uint)(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE);
140 | }
141 | return VSConstants.S_OK;
142 | }
143 | }
144 |
145 | return (int)OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED;
146 | }
147 |
148 | int IOleCommandTarget.Exec(ref Guid commandGroup, uint commandId, uint commandExecOpt, IntPtr variantIn, IntPtr variantOut)
149 | {
150 | if (commandGroup == PackageConstants.ConnectedServicesTestContextMenuCmdSet)
151 | {
152 | switch (commandId)
153 | {
154 | case PackageConstants.ConnectedServicesTestContextMenuCmdId:
155 | VsShellUtilities.ShowMessageBox(
156 | this,
157 | "Custom context menu command executed",
158 | "Custom context menu command",
159 | OLEMSGICON.OLEMSGICON_INFO,
160 | OLEMSGBUTTON.OLEMSGBUTTON_OK,
161 | OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
162 | return VSConstants.S_OK;
163 |
164 | case PackageConstants.ConnectedServicesTestContextMenuCsharpCmdId:
165 | VsShellUtilities.ShowMessageBox(
166 | this,
167 | "Custom context menu command for C# project executed",
168 | "Custom context menu command",
169 | OLEMSGICON.OLEMSGICON_INFO,
170 | OLEMSGBUTTON.OLEMSGBUTTON_OK,
171 | OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
172 | return VSConstants.S_OK;
173 | }
174 | }
175 |
176 | return (int)OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED;
177 | }
178 |
179 | #endregion IOleCommandTarget members
180 |
181 | private bool DoesCapabilityMatchForCurrentProject(string capabilityAppliesToExpression)
182 | {
183 | IVsHierarchy hierarchy = null;
184 | uint itemid = VSConstants.VSITEMID_NIL;
185 |
186 | var monitor = (IVsMonitorSelection)Package.GetGlobalService(typeof(IVsMonitorSelection));
187 | IntPtr currentHierarchy;
188 | IVsMultiItemSelect mis;
189 | IntPtr container;
190 |
191 | ErrorHandler.ThrowOnFailure(monitor.GetCurrentSelection(out currentHierarchy, out itemid, out mis, out container));
192 | try
193 | {
194 | if (currentHierarchy != IntPtr.Zero && mis == null)
195 | {
196 | hierarchy = Marshal.GetObjectForIUnknown(currentHierarchy) as IVsHierarchy;
197 | return PackageUtilities.IsCapabilityMatch(hierarchy, capabilityAppliesToExpression);
198 | }
199 |
200 | return false;
201 | }
202 | finally
203 | {
204 | if (currentHierarchy != IntPtr.Zero)
205 | {
206 | Marshal.Release(currentHierarchy);
207 | }
208 | if (container != IntPtr.Zero)
209 | {
210 | Marshal.Release(container);
211 | }
212 | }
213 | }
214 | }
215 |
216 | internal static class PackageConstants
217 | {
218 | ///
219 | /// Package GUID string.
220 | ///
221 | public const string PackageGuidString = "8EC404F4-F8AF-46C3-A2D5-1D95AA6C7AF4";
222 |
223 | ///
224 | /// Custom context menu cmd set guid
225 | ///
226 | public static readonly Guid ConnectedServicesTestContextMenuCmdSet = new Guid("6C8CF7BC-4962-4FE0-87A4-4F9DB8BE28B0");
227 |
228 | ///
229 | /// Custom context menu command
230 | ///
231 | public const int ConnectedServicesTestContextMenuCmdId = 0x0100;
232 |
233 | ///
234 | /// Custom Context Menu Command for C# projects
235 | ///
236 | public const int ConnectedServicesTestContextMenuCsharpCmdId = 0x0200;
237 |
238 | ///
239 | /// This UIContext corresponds to provider id "Microsoft.NonShipping.CustomContextMenu"
240 | ///
241 | public const string ContextMenuUIContextGuid_String = "41cb04f3-727e-7341-707f-0d3e01a95993";
242 |
243 | ///
244 | /// This UIContext corresponds to provider id "Microsoft.NonShipping.CustomContextMenu"
245 | ///
246 | public static readonly Guid ContextMenuUIContextGuid = new Guid(ContextMenuUIContextGuid_String);
247 | }
248 | ```
249 |
--------------------------------------------------------------------------------
/SDK/articles/AdvancedSeries.md:
--------------------------------------------------------------------------------
1 | # Advanced Series: From Hello World to Conversing with the world #
2 | **Note**: *this section is just a beginning. as we develop more content, this will continue to evolve*
3 |
4 | This section covers reference material. Topics you'll need information, but may not work in the same logical order. For each topic, we'll provide some additional reference links, however we don't expect you to read sequentially through as you did with the Getting Started series.
5 |
6 | ##Before you start coding##
7 |
8 | - [PowerPoint template for mocking up your Connected Service provider](./articles/ConnectedServiceProviderAuthorMockups.pptx) Mock up your provider before you start building it
9 | - [Connected Service SDK Reference APIs](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.aspx) A review of the APIs in the form of an article
10 | - [Samples for building Connected Services GitHub Repo](https://github.com/Microsoft/ConnectedServicesSdkSamples) A set of samples, such as using different configurators (Grid, SinglePage, Wizard, UILess) with Authentication, Config, and more to come...
11 |
12 | ##References, while your coding##
13 | - [Supporting Connected Services across multiple project types](./SupportingConnectedServicesAcrossMultipleProjects.md) explains how to support multiple projects. For instance, you may support .NET projects for class libraries and Windows Forms, but may want a different implementation for JavaScript or Xamarin projects.
14 | - [Modifying WPF Styles](./ModifyingWPFStyles.md) explains how to customize the WPF Styles in your configuration, without losing the underlying Visual Studio Themes
15 | - [Adding custom context menu](./AddingCustomContextMenu.md) explains how to add custom context menu to your provider folder node
16 |
17 | ##Packaging and Deploying your Connected Service Extension##
18 | - [Setting your Connected Service Extension Icon](./articles/ExtensionIcon.md)
19 |
20 |
--------------------------------------------------------------------------------
/SDK/articles/ConnectedServiceProviderAuthorMockups.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/ConnectedServices/d64431966589ef2b708e2aafea42c183d71c10b4/SDK/articles/ConnectedServiceProviderAuthorMockups.pptx
--------------------------------------------------------------------------------
/SDK/articles/ConnectedServicesExtensibilityApiContracts.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/ConnectedServices/d64431966589ef2b708e2aafea42c183d71c10b4/SDK/articles/ConnectedServicesExtensibilityApiContracts.docx
--------------------------------------------------------------------------------
/SDK/articles/ConnectedServicesExtensibilityApiContracts.md:
--------------------------------------------------------------------------------
1 | *Comming soon*
2 | A draft of this document is available in word format:
3 | [ConnectedServicesExtensibilityApiContracts.docx](ConnectedServicesExtensibilityApiContracts.docx)
--------------------------------------------------------------------------------
/SDK/articles/ConnectedServicesOverview.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/ConnectedServices/d64431966589ef2b708e2aafea42c183d71c10b4/SDK/articles/ConnectedServicesOverview.docx
--------------------------------------------------------------------------------
/SDK/articles/ConnectedServicesOverview.md:
--------------------------------------------------------------------------------
1 | *Comming soon*
2 | A draft of this document is available in word format:
3 | [ConnectedServicesOverview.docx](ConnectedServicesOverview.docx)
--------------------------------------------------------------------------------
/SDK/articles/ConnectedServicesPrinciples.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/ConnectedServices/d64431966589ef2b708e2aafea42c183d71c10b4/SDK/articles/ConnectedServicesPrinciples.docx
--------------------------------------------------------------------------------
/SDK/articles/ConnectedServicesPrinciples.md:
--------------------------------------------------------------------------------
1 | *Comming soon*
2 | A draft of this document is available in word format:
3 | [ConnectedServicesPrinciples.docx](ConnectedServicesPrinciples.docx)
--------------------------------------------------------------------------------
/SDK/articles/ConnectedServicesSDKChangesRCtoRTM.md:
--------------------------------------------------------------------------------
1 | ## Connected Services SDK Changes between Visual Studio 2015 RC and RTM ##
2 |
3 | The following is a list of breaking changes made to the Connected Services SDK from version 2.0.0-beta that shipped with Visual Studio 2015 RC and the final 2.0.0 version that ships with Visual Studio 2015 RTM.
4 |
5 | [Connected Services SDK 2.0](http://www.nuget.org/packages/Microsoft.VisualStudio.ConnectedServices/) release version is now available on NuGet
6 |
7 | - The **WizardNavigationResult** class was renamed to **[PageNavigationResult](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.pagenavigationresult.aspx)**.
8 | - **ConnectedServicesManager.ShowProviderConfigurationDialogAsync** was renamed to **[ConfigureServiceAsync](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedservicesmanager.configureserviceasync.aspx)**.
9 | - The deprecated **ConnectedServiceHyperlinkAuthenticator** class was removed.
10 | - **ConnectedServiceProvider.SupportedProjectTypes** property was removed as this feature was incomplete for RTM
11 |
12 | The following are non-breaking changes that occurred between the RC and the RTM release.
13 |
14 | - **ConnectedServicesManager.ConfigureServiceAsync** can optionally take in a **[ConfigureServiceOptions](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.configureserviceoptions.aspx)** instance. This allows for user defined "Args" to be passed into the ConnectedService Provider and Handler. The Args can be retrieved from the **[ConnectedServiceProviderContext](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.ConnectedServiceProviderContext.aspx)** and **[ConnectedServiceHandlerContext](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.ConnectedServiceHandlerContext.aspx)** objects.
15 | - **[ConnectedServicesManager.CanConfigureService](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedservicesmanager.canconfigureservice.aspx)** was added to check whether a service can be configured in the project.
16 | - **[ConnectedServicesManager.GetConfiguredServices](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedservicesmanager.GetConfiguredServices.aspx)** was added to retrieve information about the configured services in a project.
17 | - **[ConnectedServiceSinglePage.OnPageLeavingAsync](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedservicesinglepage.onpageleavingasync.aspx)** was added to support the scenario where the configure dialog should stay open when a user clicks the finish button.
18 | - **[ConnectedServiceUILess](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedserviceuiless.aspx)** class was introduced to support the scenario when a **ConnectedServiceHandler** can be invoked without prompting the user.
19 | - **[ConnectedServiceUpdateContext.Version](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedserviceupdatecontext.version.aspx)** was added to expose the version of the **ConnectedServiceProvider** that was used to previously configure the service.
20 | - **[ConnectedServiceProviderContext.GetServiceFolder](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedserviceprovidercontext.getservicefolder.aspx)** was added to support checking if a service was already configured in the current project.
21 | - **[ConnectedServiceProviderContext.InitializeUpdateContext](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedserviceprovidercontext.initializeupdatecontext.aspx)** was added to support initializing a **ConnectedServiceUpdateContext** for a previously configured service.
22 |
23 |
--------------------------------------------------------------------------------
/SDK/articles/CreatingAConnectedServiceExtension.md:
--------------------------------------------------------------------------------
1 | #Creating a Connected Service Extension
2 |
3 | The Visual Studio Connected Services feature lets app developers connect their applications to service providers that run in the cloud, or on premises. The Connected Services feature can automate the multiple steps it takes to connect a Visual Studio project to a service.
4 |
5 | The great thing about the new Connected Services experience is that it is fully extensible. Anyone can build a Visual Studio extension that adds a new Connected Service to the Add Connected Services dialog. A Connected Service can enable any Visual Studio application to connect to any service. In this article, I'm going to explain to you how to get started building your own Connected Service extension.
6 |
7 | With a custom Connected Service, you have the full power of the Visual Studio extensibility APIs to perform modifications to a developer's project. This lets you automate any steps a developer normally has to do manually to connect their application to the service.
8 |
9 | For an overview of Connected Services, see the [Connected Services overview](https://github.com/Microsoft/ConnectedServices-ProviderAuthorSamples/tree/master/docs).
10 |
11 | ## Definitions
12 |
13 | To get started, let's define some terms:
14 |
15 | 
16 |
17 | - **Connected Service Author** If you're reading this document, that's you. The author of a Connected Service extension.
18 | - **Provider** A Connected Service provider controls the UI where the app developer declares their intent and options for configuring the project to consume the service.
19 | - **Configurators** Connected Service Authors have a choice for how their provider will capture information from the app developer. Connected Services supports Grid, SinglePage and Wizard configurator implementations.
20 | - **Handler** A Connected Service handler is responsible for taking the configuration information that the app developer specifies in the configurator and modifying the service to be consumed (such as OAuth configuration) and modifying the project to consume the selected service. These modifications include adding values to app or app/web.config files, adding References, NuGets, scaffolding code, etc. Multiple handlers can be associated with a single provider to support different project types. For example, one handler can be written for ASP.NET projects, while another is written to support JavaScript Cordova projects.
21 | - **Instance** A Connected Service Instance is the hand-off of configuration data from the provider to the handler.
22 |
23 | # Writing an Extension
24 |
25 | Visual Studio uses the [Microsoft Extensibility Framework](http://msdn.microsoft.com/en-us/library/dd460648) (MEF) to load extensions. Code inside Visual Studio creates an extension point by defining a contract (which is like a .Net interface), and declaring that it "imports" the contract. Anyone who wants to plug into that extension point just has to "export" a component that adheres to the contract. At runtime, Visual Studio finds and invokes all the components that adhere to the contract.
26 |
27 | The Connected Services feature in Visual Studio does just that. It defines an extension point and a contract: the abstract [ConnectedServiceProvider](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedserviceprovider(v=vs.140).aspx) class. To create your own extension to Connected Services, you implement a class that inherits from the [ConnectedServiceProvider](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedserviceprovider(v=vs.140).aspx) class and Export it.
28 |
29 | To do this, you first need VS 2015 and the VS 2015 SDK installed.
30 |
31 | ## Creating the Connected Service Project
32 |
33 | The VS 2015 SDK installs an 'Extensibility' of project and item templates:
34 |
35 | 
36 |
37 | Choose the "VISX Project" template, which will create a new project that can extend Visual Studio, and name it " **ConnectedServiceSample**".
38 |
39 | ## Adding MEF Support
40 |
41 | Since Connected Services uses MEF to let Visual Studio know about the extension, we need to add a MEF Asset to the project
42 |
43 | - Open the source.extension.vxixmanifest file in the project, and select the Assets tab
44 | - Click the New button, and select the following values, including the name of your project.
45 |
46 | 
47 |
48 | Now you have a Visual Studio extension that can export MEF components to add functionality in VS.
49 |
50 | ## Setting Dependencies
51 |
52 | Since Connected Services is itself built as a Visual Studio extension, you'll also want to add a dependency on the Connected Services extension. Adding the dependency will warn developers attempting to uninstall the Connected Services extension that you're Connected Service will no longer work.
53 |
54 | - In source.extension.vsixmanifest, switch to the Dependencies tab and add a New Dependency. Set these field values in the dialog:
55 | - Source: "Installed extension"
56 | - Name: "Microsoft Connected Services"
57 | - Version Range: [2.0,)
58 | This value specifies version 2.0 or higher.
59 | For more info on how version ranges work see [VSIX Extension Schema 2.0 Reference](https://msdn.microsoft.com/en-us/library/hh696828.aspx)
60 |
61 | 
62 |
63 | ## Including the Connected Service in the VSIX
64 |
65 | By default, a VSIX project doesn't include the project output into the VSIX, which means you're VSIX won't actually install your Connected Service
66 |
67 | - Select the project Properties and set Include Assembly in VSIX Container to **true.**
68 |
69 | 
70 |
71 | ## Add the Connected Services SDK from NuGet
72 |
73 | With the VSIX package configured, you're ready to start adding Connected Services to your project references. The Connected Services SDK NuGet package contains the MEF contracts to build a Connected Service Extension and the XML Intellisense documents.
74 |
75 | With the project selected in Solution Explorer, choose Manage NuGet packages from the context menu.
76 |
77 | In the Package Manager window, search for **"Connected Service"**.
78 |
79 | - **Pre RTM Note:** *Be sure to check the Include prerelease checkbox*
80 |
81 | 
82 |
83 | # Creating a Provider
84 |
85 | Now that we're coding, the first step will be to get your Connected Service provider to appear in the Add Connected Service dialog
86 |
87 | In the root of the project, create a new class named Provider
88 |
89 | Add the following code
90 |
91 | using Microsoft.VisualStudio.ConnectedServices;
92 | using System;
93 | using System.Threading.Tasks;
94 | namespace ConnectedServiceSample
95 | {
96 | [ConnectedServiceProviderExport("Contoso.SampleService")]
97 | internal class Provider : ConnectedServiceProvider
98 | {
99 | public Provider()
100 | {
101 | this.Category = "Sample";
102 | this.Name = "Sample Connected Service";
103 | this.Description = "A sample Connected Services";
104 | this.Icon = null;
105 | this.CreatedBy = "Contoso";
106 | this.Version = new Version(1, 0, 0);
107 | this.MoreInfoUri = new Uri("https://aka.ms/ConnectedServicesSDK");
108 | }
109 | public override Task CreateConfiguratorAsync(ConnectedServiceProviderContext context)
110 | {
111 | return null;
112 | }
113 | }
114 | }
115 |
116 | The class inherits from the [ConnectedServiceProvider](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedserviceprovider(v=vs.140).aspx) base class and has a ConnectedServiceProviderExport attribute with one required value, the ProviderId. This string uniquely identifies the provider and is used to reference the handler. While the ProviderId must be unique, the format is by convention [Company].[Service]. Or in our case, "**Contoso.SampleService**". When we create a handler, you'll see how the ProviderId connects the handlers to the providers.
117 |
118 | The provider class specifies the property values that are used in the Add Connected Services dialog. You can choose to set the Icon property to an image resource, or 'null' if you don't have an image for testing. We recommend that you do have an image when you actually release your extension. You can see examples for setting the icon in the [Connected Services Samples](https://github.com/Microsoft/ConnectedServicesSdkSamples).
119 |
120 | We'll discuss the [CreateConfiguratorAsync](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedserviceprovider.createconfiguratorasync(v=vs.140).aspx) method later when we need to fill it out. For now, we'll just return 'null'.
121 |
122 | This is the minimum information that Visual Studio needs to show your extension in the Add Connected Services dialog.
123 |
124 | ## Debugging Your Provider
125 |
126 | When you start debugging (F5) your project, Visual Studio will launch an [Experimental Instance of Visual Studio](https://msdn.microsoft.com/en-us/library/bb166560.aspx). The Experimental Instance is a sandboxed instance of Visual Studio where you can try out your extensions while they are in development without affecting your real Visual Studio installation. If you are having problems with getting F5 to work, make sure the Debug settings in your startup project properties are set to the following:
127 |
128 | 
129 |
130 |
131 | In the Experimental Instance of Visual Studio, create a new Console Application project, and right-click the project in the solution "Add -> Connected Service…" and you will see your new provider in the dialog:
132 |
133 | 
134 |
135 |
136 | Notice that the "Configure" button is disabled in the Connected Service dialog. A Connected Service provider needs to find a class that handles the configuration for the project. Because there is no available handler with the same ProviderId that supports the current project type, Visual Studio disables the Configure button.
137 |
138 | To enable the button, we will need to create a handler for this provider and project type.
139 |
140 | # Creating a Handler
141 |
142 | Stop debugging, and add a new class named **Handler** to the root of your project with the following code:
143 |
144 | using Microsoft.VisualStudio.ConnectedServices;
145 | using System;
146 | using System.Threading;
147 | using System.Threading.Tasks;
148 | namespace ConnectedServiceSample
149 | {
150 | [ConnectedServiceHandlerExport("Contoso.SampleService",
151 | AppliesTo = "CSharp+Web")]
152 | internal class Handler : ConnectedServiceHandler
153 | {
154 | public override Task AddServiceInstanceAsync(ConnectedServiceHandlerContext context, CancellationToken ct)
155 | {
156 | AddServiceInstanceResult result = new AddServiceInstanceResult(
157 | "Sample",
158 | new Uri("https://github.com/Microsoft/ConnectedServicesSdkSamples"));
159 | return Task.FromResult(result);
160 | }
161 | }
162 | }
163 |
164 | Visual Studio finds handlers in the same way that it finds providers, using MEF. This class is decorated with a ConnectedServiceHandlerExport attribute, allowing VS to find it when it searches for available handlers. The attribute's first parameter matches the ProviderId of the provider. This is how providers and handlers are matched up. A handler specifies which provider it corresponds to using a matching ProviderId value.
165 |
166 | The value of the attribute's AppliesTo parameter specifies what types of Visual Studio projects this handler supports. The full syntax for specifying these strings is available in the [AppliesTo](http://msdn.microsoft.com/en-us/library/dn497698.aspx) documentation on MSDN. The one used in the example declares that any C# Web project is supported. If you have a console application, or any VB project, the Configure button will remain disabled. But for C# Web projects, the Configure button will be enabled.
167 |
168 | You will implement the changes to the app developer's project in the AddServiceInstanceAsync method. We'll show you to do in a later section. For now, we simply return a simple instance of the AddServiceInstanceResult.
169 |
170 | F5 again, create a C# Web project, open the Connected Service dialog, and you will see the sample provider can now be configured.
171 |
172 | Now that the Configure button is enabled, you are probably going to want to click it. However, if you do, you get the exception message:
173 |
174 | _The Connected Services component ' Sample Provider' failed: (HRESULT:0x80131509) The Connected Service Provider 'Contoso.SampleService' returned an invalid ConnectedServiceConfigurator from the CreateConfiguratorAsync method. A valid object should inherit from ConnectedServiceGrid, ConnectedServiceSinglePage, or ConnectedServiceWizard._
175 |
176 | # Creating a Configurator
177 |
178 | The provider creates a configurator to collect required and optional data that is needed add the service to the app developer's project. The data is returned as a ConnectedServiceInstance object which the provider supplies to the handler.
179 |
180 | Implementing the [CreateConfiguratorAsync](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedserviceprovider.createconfiguratorasync(v=vs.140).aspx) method leads to one of the first big choices you make about how you want to collect the app developer's configuration choices. Depending on the size and complexity of the choices, you can choose between the "Grid", "SinglePage" or "Wizard" configurator templates.
181 |
182 | ## [Grid](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedservicegrid(v=vs.140).aspx)
183 |
184 | The Grid configurator is a list of services from which the app developer chooses. While the Grid configurator is the easiest to implement, it is also the most restrictive in the kind and complexity of the user's possible choices.
185 |
186 | 
187 |
188 | ## [Single Page](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedservicesinglepage(v=vs.140).aspx)
189 |
190 | The SinglePage configurator lets you implement a WPF user control that takes up most of the configurator dialog. In the user control, you can use any set of WPF controls to collect the user's data.
191 |
192 | 
193 |
194 | ## [Wizard](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedservicewizard(v=vs.140).aspx)
195 |
196 | The Wizard control lets the user navigate among a number of configurator pages. Like the SinglePage configurator, you implement a user control for each page to collect the data.
197 |
198 | 
199 |
200 | We'll show you how to implement a SinglePage configurator and return it as a [ConnectedServiceSinglePage](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedservicesinglepage.aspx) object to the provider.
201 |
202 | ## WPF, MVVM and Connected Service Templates
203 |
204 | Configurator UIs are created using a variation of the WPF Model-ViewModel-View (MVVM) design pattern that separates the data and logic of the UI (the ViewModel class) from the XAML that displays it (the View class). The behavior of View elements are controlled by the ViewModel through WPF data binding.
205 |
206 | The Connected Services runtime supplies the View for the Grid configuator, you only have to describe the list items in a class derived from the abstract ConnectedServiceGrid ViewModel.
207 |
208 | The Connected Services runtime provides the outer dialog frame for all configurators. When you add a WPF user control and derive its ViewModel from one of the three configurators (ConnectedServiceGrid, ConnectedServiceSinglePage, ConnectedServiceWizardPage), the parent View incorporates the control and user-defined values.
209 |
210 | # Implementing a SinglePage Configurator
211 |
212 | To get started with a SinglePage configuration, aligning with the MVVM pattern, we need two classes; the View and the ViewModel, and we'll place them in grouped folders:
213 |
214 | - Create two folders for the **Views** and **ViewModels**.
215 | - Add an empty class named **SinglePageViewModel.cs** to a **ViewModels** folder
216 | - Add a WPF UserControl named **SinglePageView.xaml** to the **Views** folder.
217 | Select the Views folder. From the context menu, choose.Add New Item, then choose User Control (WPF).
218 |
219 | Your project should now look like the following:
220 |
221 | 
222 |
223 |
224 | ## Implementing the SinglePageViewModel Class
225 |
226 | The SinglePageViewModel class collects and stores the user data. In our simple case, we'll simply capture the name the developer wishes to name their service instance.
227 |
228 | To start with, we need to inherit from the [ConnectedServiceSinglePage](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedservicesinglepage(v=vs.140).aspx) class. This class provide the basic Connected Service functionality to your provider.
229 |
230 | Replace the ViewModel class with the following code:
231 |
232 | using Microsoft.VisualStudio.ConnectedServices;
233 | using System.Threading.Tasks;
234 | namespace ConnectedServiceSample.ViewModels
235 | {
236 | public class SinglePageViewModel : ConnectedServiceSinglePage
237 | {
238 | public SinglePageViewModel()
239 | {
240 | this.View = new Views.SinglePageView();
241 | this.View.DataContext = this;
242 | this.Title = "Contoso Sample Provider";
243 | this.Description = "Configure the Contoso Service";
244 | }
245 | public override Task GetFinishedServiceInstanceAsync()
246 | {
247 | ConnectedServiceInstance instance = new ConnectedServiceInstance();
248 | return Task.FromResult(instance);
249 | }
250 | }
251 | }
252 |
253 | In this example, we only want the app developer to provide us a name for the service instance. To store the name, we'll create a property named ServiceName. To make sure our WPF View gets updated, we'll follow the MVVM databinding pattern and raise an [INotifyPropertyChanged](https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx) event. Rather than have to implement this pattern yourself, the ConnectedServiceSinglePage class provides an OnPropertyChanged method. Better yet, you don't even need to pass the name of the property in quotes. The value is calculated for you.
254 |
255 | Add the following property definition to the SinglePageViewModel
256 |
257 | private string _serviceName;
258 | public string ServiceName
259 | {
260 | get { return _serviceName; }
261 | set
262 | {
263 | if (value != _serviceName)
264 | {
265 | _serviceName = value;
266 | OnPropertyChanged();
267 | }
268 | }
269 | }
270 |
271 | ## Enabling the Add button
272 |
273 | By default, the Add button is disabled. The assumption is your developer must do something before they can complete the configuration. In our case, we just need a valid ServiceName.
274 |
275 | In the constructor, define an event handler for the PropertyChanged event:
276 |
277 | public SinglePageViewModel()
278 | {
279 | this.View = new Views.SinglePageView();
280 | this.View.DataContext = this;
281 | this.Title = "Contoso Sample Provider";
282 | this.Description = "Configure the Contoso Service";
283 | this.PropertyChanged += SinglePageViewModel_PropertyChanged;
284 | }
285 |
286 | Then, do some validation. In our case, it's pretty simple:
287 |
288 | private void SinglePageViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
289 | {
290 | this.IsFinishEnabled = !string.IsNullOrWhiteSpace(ServiceName);
291 | }
292 |
293 | We'll use the ServiceName value as the name of the Connected Service folder, and the name referenced in the app project's config file. To set this up, in the GetFinishedServiceInstanceAsync method, set the instance.Name to the ServiceName property we've asked our developer to provide. Your code should look like the following:
294 |
295 | public override Task GetFinishedServiceInstanceAsync()
296 | {
297 | ConnectedServiceInstance instance = new ConnectedServiceInstance();
298 | instance.Name = this.ServiceName;
299 | return Task.FromResult(instance);
300 | }
301 |
302 | Now, when your developer tabs out of the ServiceName textbox, the validation will kick in, and enable the Add button
303 |
304 | ## Adding the SinglePage View
305 |
306 | Now that we have our ViewModel with the information we need to capture, let's create a View over it.
307 |
308 | - To get a sense of how much space you have to work with, we can set the design time height and width.
309 | - To get the designtime databinding we'll add the designtime DataContext. We first add an alias to our ViewModels namespace, then we set the designtime datacontext.
310 |
311 | Your UserControl declaration should now look like the following:
312 |
313 |
323 |
324 | To capture the service name, we'll replace the empty WPF Grid layout control with a StackPanel that contains a label and textbox that is bound to the ServiceName property of the SinglePageViewModel class.
325 |
326 |
327 |
328 |
329 |
330 |
331 | ## Connectinging the Configurator to the Provider
332 |
333 | With our View and ViewModel now ready, we'll want to tell the provider where to find them. To hook our SinglePageView to our provider, we'll go back to the CreateConfiguratorAsync method.
334 |
335 | Open the **Provider** class and update the CreateConfiguratorAsync with the following code:
336 |
337 | public override Task CreateConfiguratorAsync(ConnectedServiceProviderContext context)
338 | {
339 | ConnectedServiceConfigurator configurator = new ViewModels.SinglePageViewModel();
340 | return Task.FromResult(configurator);
341 | }
342 |
343 | In this code snippet the **CreateConfiguratorAsync** method was overridden to return a new instance of the SinglePageViewModel we've created, which defines the view used.
344 |
345 | ## Try it out
346 |
347 | If you F5 your extension now, load a Web project, open the Connected Services dialog, and click the Configure button for the Sample provider you will see your SinglePage template populated.
348 |
349 | 
350 |
351 | ###Other UI Options
352 |
353 | This is the minimum needed to create a UI and collect data using a SinglePage configurator. But there are other customization options you can choose such as overriding the CreateAuthenticatorAsync method to add a WPF control in the top right of the dialog that can sign users into your service.
354 |
355 | For example, you could use a hyperlink to pop open a sign in dialog, or integrate with Visual Studio's Account Picker control to get an account from the KeyChain.
356 |
357 | See the [SinglePageAuth sample](https://github.com/Microsoft/ConnectedServicesSdkSamples/tree/master/src/Auth/SinglePage) for more info.
358 |
359 | # Making Project Changes
360 |
361 | We're now ready to create the UI for our sample service provider. The Provider class specifies the information to show in the Add Connected Services selection dialog. Selecting a Connected Service initializes the SinglePageViewModel to create the UI to collect user information with the SinglePageView. Once the developer chooses **[Add]**, the SinglePageViewModel configurator creates the ConnectedServiceInstance to pass to the Handler. We now need to implement the Handler class to make the changes to the app project that adds our service.
362 |
363 | Handler classes derived from the [ConnectedServiceHandler](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedservicehandler.aspx) class to implement specific project changes. Handlers are associated with specific project types based on the AppliesTo attribute. In many cases you'll have more than one handler. For instance, you may want to provide service configurations for ASP.NET C# and VB projects. This of course uses C# and VB.NET code and .NET References. However, if you want to support JavaScript projects, like Cordova, you'll need to add JavaScript to the project, including various script files. Or, you may want to target ASP.NET 5 or UAP Windows projects, which uses different coding patterns, references and a config.json file.
364 |
365 | In our basic sample project, we'll just add a value to the app's web.conig file, and create a folder in the app's project hierarchy for artifacts we might need as we expand the service functionality.
366 |
367 | ## Implementing the Handler Class
368 |
369 | Open the Handler class and notice the method AddServiceInstanceAsync. The method returns a Task, so if you need to write asynchronous code, you can implement the async/await pattern. The result of the Task is an object of type AddServiceInstanceResult, which takes two values: a " **folder name"** and a " **getting started**" URL. When the handler is finished executing, a folder will be created under the "Service References" folder that will contain the Connected Service artifacts. The "getting started" URL is a link to documentation that you want to show your developers to get them started using the connected service.
370 |
371 | The input into AddServiceInstanceAsync is a ConnectedServiceHandlerContext object that's provided by the Connected Services runtime. The context parameter contains all the input information to the handler. Some important members of this class are:
372 |
373 | - ** The ProjectHierarchy property represents the VS Project that should be modified. At this point, anything that is possible to do with Visual Studio extension APIs can be invoked to manipulate the project using [IVsHierarchy](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.ivshierarchy.aspx)
374 | - ** The [ServiceInstance](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedserviceinstance.aspx) property contains the information that was configured by the provider and returned in the [GetFinishedServiceInstanceAsync](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedservicesinglepage.getfinishedserviceinstanceasync.aspx) method on the SinglePageViewModel. It contains the name of the service, and any other information the provider wants to give to the handler. Connection information related to the service your configuring is a common piece of data to pass along in the ServiceInstance.
375 | - ** The [Logger](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedservicelogger(v=vs.140).aspx) property is used for writing debugging information and other messages you wish the developer to see. This information is displayed in progress dialog, and it is logged to the Visual Studio Output window as well. By setting the [Category](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.loggermessagecategory.aspx), you can specify how the message is communicated to the developer.
376 |
377 | ## Making Project Changes
378 |
379 | Most providers will make several changes to the project. Some changes may take some time, such as adding NuGets, references, or calling services to retrieve metadata to scaffold code. While making project changes, using the async/await pattern and the Logger, you can actively report progress to the developer letting them know what's happening. Output sent thru the Logger is also sent to the Output window.
380 | As an example of what you can do to the project, let's add the name of our service to the web.config file and we'll show how the Logger and Progress dialog work.
381 |
382 | If you choose to support class libraries, Console, WinForm or WPF apps, the same code will manage app.config files as well.
383 |
384 | In the **Handler** class, replace the **AddServiceInstnaceAsync** method with the following:
385 |
386 | publicasyncoverrideTask AddServiceInstanceAsync(ConnectedServiceHandlerContext context, CancellationToken ct)
387 | {
388 | await context.Logger.WriteMessageAsync(LoggerMessageCategory.Information, "Updating Config");
389 | using (EditableXmlConfigHelper configHelper = context.CreateEditableXmlConfigHelper())
390 | {
391 | configHelper.SetAppSetting(
392 | string.Format("{0}:ConnectionString", context.ServiceInstance.Name),
393 | "SomeServiceConnectionString",
394 | context.ServiceInstance.Name
395 | );
396 | configHelper.Save();
397 | }
398 | Thread.Sleep(1000);
399 | await context.Logger.WriteMessageAsync(LoggerMessageCategory.Information, "Adding NuGets");
400 | Thread.Sleep(1000);
401 | await context.Logger.WriteMessageAsync(LoggerMessageCategory.Information, "Adding References");
402 | Thread.Sleep(1000);
403 | AddServiceInstanceResult result = newAddServiceInstanceResult(
404 | context.ServiceInstance.Name,
405 | newUri("https://github.com/Microsoft/ConnectedServicesSdkSamples"));
406 | return result;
407 | }
408 |
409 | Reviewing the code above:
410 |
411 | - We've made the method async to support awaiting the various steps. Using async and await, the Connected Services UI will remain responsive to the developer.
412 | - We use the [Logger](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedservicelogger.aspx) to inform the developer of the progress
413 | - We use an EditableXmlConfigHelper class to interact with web/app.config files. Note the use of the Save and IDisposable pattern to assure we're closing out the file resource.
414 | - In the EditableXmlConfigHelper we specify the Name/Value pair of the config entries, and we can also add a comment. In large projects, this can be really helpful to isolate your specific service settings. Notice we use the ServiceName to individually identify the config names. Many services, such as SQL or Azure Storage may be consumed multiple times in a single project, so you'll want to allow your developer to individually name these configuration values.
415 | - We call Thread.Sleep to simulate activities and logger messages to show the execution steps in the progress dialog.
416 | - Finally, we return a AddServiceInstanceResult object with the name of our service, and the uri of our Getting Started document.
417 |
418 | ## Running the Completed Connected Service Project
419 |
420 | Press F5 to run the project.
421 |
422 | In the Visual Studio Experimental Instance, open or create a C# Web Project. Choose Add Connected Service and then choose the sample connected service. Enter a ServiceName such as **MyService** , press Tab and click the Add button.
423 |
424 | So, what happens?
425 |
426 | - The progress dialog is displayed while the handler is executing.
427 |
428 | 
429 |
430 | - Values are added to web.config file.
431 |
432 |
433 |
434 |
435 |
436 | - A Connected Service folder is created in the Service References of the project, named MyService based on the folder name passed thru the AddServiceInstanceResult
437 |
438 | 
439 |
440 | # A Getting Started virtual node is created to help your developers get back to your docs after they close the page.What Next?
441 |
442 | At this point, the code you need to write depends on your service's requirements. Some common things that handlers implement are:
443 |
444 | - Authenticate against, and configure your service for OAuth consumption. This typically incudes provisioning a ConsumerSecret and Token.
445 | - Installing a NuGet package for runtimes your service depends upon, such as a client SDK.
446 | See the " [Invoking NuGet Services from inside Visual Studio](http://docs.nuget.org/docs/reference/invoking-nuget-services-from-inside-visual-studio)" article for more information on automating NuGet tasks.
447 | - To increase the stability and performance of your provider, we recommend embedding the NuGet package(s) your Connected Service requires in your Visual Studio extension instead of downloading the package from a remote repository. See the [IVsPackageInstaller.InstallPackagesFromVSExtensionRepository](http://docs.nuget.org/docs/reference/Extensibility-APIs) method for more information.
448 |
449 | - Modifying the application's configuration (app.config, web.config, config.json, etc.)
450 | - Adding references
451 |
452 | - Scaffolding code into the project typically done with user modifiable T4 templates. See the [Salesforce Connected Service Reference Implementation](https://github.com/developerforce/visual-studio-tools) for an example of T4 template usage.
453 |
454 | - Adding non-code files.
455 |
456 | The last four tasks can be accomplished with helper methods in the ConnectedServiceHandlerContext object.
457 |
458 | We'll continue to make additional samples available over time in the [Connected Services Samples Repo](https://github.com/Microsoft/ConnectedServicesSdkSamples)sitory. For a complete reference implementation, please see the open source [Connected Service Salesforce provider](https://github.com/developerforce/visual-studio-tools).
459 |
460 | ## Publish your VSIX to the Visual Studio Gallery
461 |
462 | As you may have noticed in the Add Connected Services dialog, there's a link to find more… This launches the Extensions & Updates dialog, which is a view into the [Visual Studio Gallery](https://visualstudiogallery.msdn.microsoft.com/site/search?f%5B0%5D.Type=RootCategory&f%5B0%5D.Value=tools&f%5B0%5D.Text=Tools&f%5B1%5D.Type=SubCategory&f%5B1%5D.Value=tools_connectedservices&f%5B1%5D.Text=Connected%20Services&f%5B2%5D.Type=VisualStudioVersion&f%5B2%5D.Value=14.0&f%5B2%5D.Text=Visual%20Studio%2014), with the Connected Services tools category selected.
463 |
464 | So, go ahead and upload your provider, and help developers easily consume your services.
465 |
466 | # Summary
467 |
468 | Now you have the complete Visual Studio extensibility APIs at your disposal to build up your Connected Service extension. To leave us feedback or get feedback on your provider implementation, please contact us through the [Connected Services UserVoice forum](https://visualstudio.uservoice.com/forums/265038-connected-services)
469 |
470 | # References
471 |
472 | - [Connected Services Home page](https://github.com/Microsoft/ConnectedServices)
473 | - [Connected Services SDK Home page](https://github.com/Microsoft/ConnectedServices/SDK)
474 | - [Connected Services SDK Reference Documents](https://msdn.microsoft.com/en-us/library/dn930812(v=vs.140).aspx)
475 | - [Connected Services Samples Git Repo](https://github.com/Microsoft/ConnectedServicesSdkSamples)sitory
476 | - [Connected Service Sample from this walk through](https://github.com/Microsoft/ConnectedServicesSdkSamples/tree/master/src/Walkthroughs/ConnectedServiceSample)
477 | - [Connected Services UserVoice forum](https://visualstudio.uservoice.com/forums/265038-connected-services)
478 | - [Salesforce Connected Service Reference Implementation](https://github.com/developerforce/visual-studio-tools)
479 | - [VSIX Deployment](https://msdn.microsoft.com/en-us/library/ff363239.aspx)
480 | - [VSIX Extension Schema 2.0 Reference](https://msdn.microsoft.com/en-us/library/hh696828.aspx)
481 | - [Visual Studio Gallery](https://visualstudiogallery.msdn.microsoft.com/site/search?f%5B0%5D.Type=RootCategory&f%5B0%5D.Value=tools&f%5B0%5D.Text=Tools&f%5B1%5D.Type=SubCategory&f%5B1%5D.Value=tools_connectedservices&f%5B1%5D.Text=Connected%20Services&f%5B2%5D.Type=VisualStudioVersion&f%5B2%5D.Value=14.0&f%5B2%5D.Text=Visual%20Studio%2014)
482 | - [Experimental Instance of Visual Studio](https://msdn.microsoft.com/en-us/library/bb166560.aspx)
483 | - [MVVM Overview by John Papa](http://www.johnpapa.net/5-minute-overview-of-mvvm-in-silverlight/)
484 | - [MVVM by Josh Smith](https://msdn.microsoft.com/en-us/magazine/dd419663.aspx)
485 |
--------------------------------------------------------------------------------
/SDK/articles/DosAndDonts.md:
--------------------------------------------------------------------------------
1 | #The Do's and Don'ts for authoring Connected Services#
2 |
3 | The following are common do's and don'ts to consider when building a Connected Service.
4 |
5 | The first of which is:
6 |
7 | - Do read the **[Principles doc]()** Yes, it's long, but it has all the guiding principles for how to build a successful Connected Service
8 | - Don't **just read this**, assuming the brief bullets explain the "why" for the do's and don'ts
9 | - Do **use this as a reminder** of the things to look for, and what your developers will be looking for as they use your Connected Service
10 |
11 |
12 | ## Discovery/Selection Experience ##
13 | Here's some things to consider, relating to the general user experience, including how to surface your information in Service Selection and Configuration.
14 |
15 | 
16 |
17 | - Do list your Connected Service in the **left category listing** by its technology instead of using your company name. While it's nice to advertise your company, will developers be looking for your company, or will they be looking for specific service types. For instance, developers may not know of Datalogics, but they do want PDF services.
18 | - Don't use the **category as an advertisement** for your company, use the **[Created By](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedserviceprovider.createdby.aspx)** property
19 | - Don't create **multiple entry points** in various menus just so developers can find your service.
20 | - Do **provide update** scenarios, helping your developers get continual value. See the [sample for Update](https://github.com/Microsoft/ConnectedServicesSdkSamples/tree/master/src/UpdateSupport)
21 |
22 | ## Configuration Experience ##
23 | 
24 |
25 | - Do **capture all the information** in the configurators, and **wait to configure the service and project** after the developer presses the [Add/Update/Finish] button
26 | - Don't **make any service or project changes** before the user presses the [Add/Update/Finish]
27 | - Do **keep the user in the Connected Services configuration** experience, doing all the required server side configuration for them
28 | - Don't create **new windows** to show progress or messages
29 | - Don't create a **list of TODO's**, like goto this link, do these steps, copy this value, ...
30 | - Do take advantage of the [Connected Service and signature dialog WPF styles](./ModifyingWPFStyles.md) to handle the various **Visual Studio themes**
31 | - Do **provide MRUs** for all values the developer may have to enter
32 | - Don't make the developer **look up things** you can do for them, such as the list of URLs for production and staging endpoints of your service.
33 | - Do **cache their design time user-name and OAuth tokens** to avoid having to login each time
34 | ## Long Running Operations ##
35 | - Do use the **[Progress Indicator](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedserviceprovidercontext.startbusyindicator.aspx)** for long running operations. See the [Samples for Progress Indicators](https://github.com/Microsoft/ConnectedServicesSdkSamples/tree/master/src/ProgressIndicators)
36 | - Do provide **progress during handler** configuration using the [Logger](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.connectedservicelogger.aspx) classes
37 |
38 |
39 | # Making Service and Project Changes #
40 | Developers may select your Connected Service, they may even go part way through the configuration, but they may realize they don't have everything ready, or were just curious. To maintain a trust that they can safely explore without doing damage, you should never make service or project changes until they press the Add/Update/Finish. Committing changes should be done in the handler.
41 | The one exception many of the Azure services have done is create some of the endpoints. For instance, you can't connect to a Storage Account unless it exists. This was actually a leftover from the Visual Studio 2013 implementation, and is limited by the design of the GridConfigurator. If we were to re-design these experiences, we'd follow the experience we built for Salesforce, and capture the name of the storage account, and defer to creating it in the handler, after the user pressed Add/Update/Finish.
42 |
43 | # Project Configuration #
44 | - Do provide **templates for any code** scaffolded into their projects. Use T4, razor, or other appropriate templates
45 | - Do **preserve their template customization's** when the developer uninstalls or upgrade your connected service
46 | - Do consider your developers may want/need **multiple instances** of your service, and allow them to name the instance added
47 | - Do **scaffold only the unique code** to their service/project
48 |
49 |
50 | ## Generating vs. Scaffolding ##
51 | The details of retiring the "Can't Touch This" style of code generation and tooling. For more info, see this [7 min video](https://channel9.msdn.com/Series/Visual-Studio-2015-Enterprise-Videos/Connecting-to-Services-with-Visual-Studio).
52 |
53 | - Do **use SDKs and Client Libraries** for the common code across all service instances
54 | - Don't assume Connected Services is just a **customizable Add Service Reference** to generate lots of code
55 | - Do **scaffold the code** your developers will need 90%, not 80% of the time
56 | - Don't **generate code** into their project that gets replaced when they update the service
57 | - Do **use [roslyn]()** to understand their project artifacts
58 | - Do scaffold code in the **same way the developer would write the code** themselves. For instance, add `using ` statements
59 | - Don't generate types with fully qualified namespaces
60 | - Do scaffold code using **best practices** for the specific API/scenario
61 |
62 | ## Performance ##
63 | - Do **cache NuGets** in your VSIX for performance and stability of your configuration
64 | - Do all service calls and lengthy operations using the **async** pattern
65 |
66 | ## Configuration ##
67 | - Don't persist **design time information** that can get out of sync with their code
68 | - Do save **hints* in the ConnectedService.json file for where artifacts may be
69 | - Don't create additional designer files
70 | - Don't **fail if the hints are invalid**, or the developer moved the artifacts from where they were the first time
71 | - Do **put code comments and config headings** at the top of your config entries with the [SetAppSetting](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.editablexmlconfighelper.setappsetting.aspx) API
72 |
73 | # Getting Started Documentation #
74 | - Do **provide getting started online pages** that explain what you did for them, to your service, and to *their* project with the [GettingStartedDocument](https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.connectedservices.addserviceinstanceresult.gettingstarteddocument.aspx) property
75 | - Do provide the **hello world samples** in the getting started pages
76 | - Don't add **sample code** to their project, even if you think about giving them a checkbox.
77 |
78 | # General Development #
79 | - Do consider making your Connected Service **open source** as others may want to improve your connected service, and if it improves your service usage, why not
80 | - Do consider the [.NET Foundation](http://www.dotnetfoundation.org/) to help mitigate legal concerns of going open source
81 | - Do consider **versioning** your VSIX, Provider, Assembly consistently
82 | - Do take the time to learn **MVVM** as it will make your development much easier to manage state between configuration steps
83 | - Do use **client libraries/SDKs** that match each project type
84 | - Do the **right thing for the specific project**
85 | - Don't attempt to make **all project types work the same** (JavaScript, Python, .NET). See [Supporting Connected Services across multiple project types](./SupportingConnectedServicesAcrossMultipleProjects.md)
86 | - Do **reference, copy, clone, infer, borrow code** from the [Connected Service Samples]() and the [Salesforce Connected Service](), open source reference implementation
87 | - Do use [GitHub issues]() to engage with us, log issues, make suggestions
88 | - Do **engage with us** to help you build a great Connected Service experience
89 |
--------------------------------------------------------------------------------
/SDK/articles/ExtensionIcon.md:
--------------------------------------------------------------------------------
1 | #Setting The Extension Icon#
2 | Creating a nice Icon for your Visual Studio Connected Service extension is a nice touch. But, something you may not have time to mess around with either. Looking at the Visual Studio gallery, you can see that many extensions use the default icon, but it may just be a few elusive settings.
3 |
4 | 
5 |
6 | If you're trying to set the icon, but having troubles, here's a quick few tips:
7 |
8 | - Set the icon in the `source.extension.vsixmanifest` file
9 |
10 | 
11 |
12 | Confirm a few properties are set on the ExtensionIcon file:
13 |
14 | - Icon Size = **32x32**, in a **.png** format *(others may work, but I know this does)*
15 | - Build Action = **Content**
16 | - Copy to Output Directory = **Do not copy**
17 | - Include in VSIX = **True**
18 |
19 | 
20 |
21 | With these few properties, you can have a full set of connected clouds:
22 | 
23 |
24 |
--------------------------------------------------------------------------------
/SDK/articles/GettingStartedSeries.md:
--------------------------------------------------------------------------------
1 | # Getting Started Series: Hello World of Connected Services #
2 | **Note**: *this section is just a beginning. as we develop more content, this will continue to evolve*
3 |
4 | This section is your getting started content, to get your initial Connected Service up and running. While we've grouped content into sections, we expect you'll read through this group sequentially to create your baseline Connected Service. You might think these topics as reading a book, with a continuous story with chapters as just pauses in the continuing story.
5 | Once you're finished with this section, you'll move onto the [Advanced Series](./AdvancedSeries.md), which will be more like a reference book, where you skip around to different chapters based on what you're focused on at the time.
6 |
7 | - [Pre Requisites for building a Connected Service](./PrerequisiteComponents.md)
8 | - [Walkthrough for building a Connected Service](./CreatingAConnectedServiceExtension.md)
9 | - [Overview for building a Connected Service](./ConnectedServicesOverview.md)
10 |
--------------------------------------------------------------------------------
/SDK/articles/ModifyingWPFStyles.md:
--------------------------------------------------------------------------------
1 | #Modifying the WPF Styles#
2 | By default, the base implementation of Connected Services will default all the styles to match the light, dark and blue themes of Visual Studio. These styles ship as part of Visual Studio, to support what we call the Signature Dialog theme.
3 |
4 | In most cases, you shouldn't have to make changes to the styles. However, if you do need to make a change, such as adding a watermark to help customers understand how to use the control, you'll need to tweak the style. However, you'll need to know the base styles so you don't replace the base style, rather enhance it.
5 |
6 |
7 |
8 | ## Adding the .NET assembly reference ##
9 | To access the WPF Signature Dialog styles included with Visual Studio, add a reference to:
10 |
11 | - `Microsoft.VisualStudio.Shell.14.0`
12 |
13 | This assembly is included in the VS SDK.
14 |
15 | ## Adding the XAML reference ##
16 | To reference the styles in XAML, add the following XAML reference to the UserControl definition:
17 | `xmlns:vsfx="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.14.0"`
18 |
19 | The Salesforce [ObjectPicker.xaml](https://github.com/developerforce/visual-studio-tools/blob/master/src/Salesforce.VisualStudio.Services/ConnectedService/Views/ObjectPicker.xaml) view now looks like:
20 |
21 |
28 |
29 | ## Setting the BasedOn property ##
30 | To customize the control, set the relevant properties, but include the [BasedOn](https://msdn.microsoft.com/en-us/library/system.windows.style.basedon.aspx) property to the Visual Studio themes.
31 | For example: `BasedOn="{StaticResource {x:Static vsfx:VsResourceKeys.ThemedDialogTreeViewItemStyleKey}`
32 |
33 |