{"action":"created","issue":{"url":"https://api.github.com/repos/Microsoft/VSSDK-Analyzers/issues/68","repository_url":"https://api.github.com/repos/Microsoft/VSSDK-Analyzers","labels_url":"https://api.github.com/repos/Microsoft/VSSDK-Analyzers/issues/68/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/VSSDK-Analyzers/issues/68/comments","events_url":"https://api.github.com/repos/Microsoft/VSSDK-Analyzers/issues/68/events","html_url":"https://github.com/Microsoft/VSSDK-Analyzers/pull/68","id":333036926,"node_id":"MDExOlB1bGxSZXF1ZXN0MTk1MzYyMzcz","number":68,"title":"Add VSSDK006 Check service exists analyzer","user":{"login":"AArnott","id":3548,"node_id":"MDQ6VXNlcjM1NDg=","avatar_url":"https://avatars2.githubusercontent.com/u/3548?v=4","gravatar_id":"","url":"https://api.github.com/users/AArnott","html_url":"https://github.com/AArnott","followers_url":"https://api.github.com/users/AArnott/followers","following_url":"https://api.github.com/users/AArnott/following{/other_user}","gists_url":"https://api.github.com/users/AArnott/gists{/gist_id}","starred_url":"https://api.github.com/users/AArnott/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AArnott/subscriptions","organizations_url":"https://api.github.com/users/AArnott/orgs","repos_url":"https://api.github.com/users/AArnott/repos","events_url":"https://api.github.com/users/AArnott/events{/privacy}","received_events_url":"https://api.github.com/users/AArnott/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"AArnott","id":3548,"node_id":"MDQ6VXNlcjM1NDg=","avatar_url":"https://avatars2.githubusercontent.com/u/3548?v=4","gravatar_id":"","url":"https://api.github.com/users/AArnott","html_url":"https://github.com/AArnott","followers_url":"https://api.github.com/users/AArnott/followers","following_url":"https://api.github.com/users/AArnott/following{/other_user}","gists_url":"https://api.github.com/users/AArnott/gists{/gist_id}","starred_url":"https://api.github.com/users/AArnott/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AArnott/subscriptions","organizations_url":"https://api.github.com/users/AArnott/orgs","repos_url":"https://api.github.com/users/AArnott/repos","events_url":"https://api.github.com/users/AArnott/events{/privacy}","received_events_url":"https://api.github.com/users/AArnott/received_events","type":"User","site_admin":false},"assignees":[{"login":"AArnott","id":3548,"node_id":"MDQ6VXNlcjM1NDg=","avatar_url":"https://avatars2.githubusercontent.com/u/3548?v=4","gravatar_id":"","url":"https://api.github.com/users/AArnott","html_url":"https://github.com/AArnott","followers_url":"https://api.github.com/users/AArnott/followers","following_url":"https://api.github.com/users/AArnott/following{/other_user}","gists_url":"https://api.github.com/users/AArnott/gists{/gist_id}","starred_url":"https://api.github.com/users/AArnott/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AArnott/subscriptions","organizations_url":"https://api.github.com/users/AArnott/orgs","repos_url":"https://api.github.com/users/AArnott/repos","events_url":"https://api.github.com/users/AArnott/events{/privacy}","received_events_url":"https://api.github.com/users/AArnott/received_events","type":"User","site_admin":false}],"milestone":null,"comments":1,"created_at":"2018-06-17T05:33:26Z","updated_at":"2018-06-17T05:47:43Z","closed_at":null,"author_association":"MEMBER","pull_request":{"url":"https://api.github.com/repos/Microsoft/VSSDK-Analyzers/pulls/68","html_url":"https://github.com/Microsoft/VSSDK-Analyzers/pull/68","diff_url":"https://github.com/Microsoft/VSSDK-Analyzers/pull/68.diff","patch_url":"https://github.com/Microsoft/VSSDK-Analyzers/pull/68.patch"},"body":"# VSSDK006 Check service exists\r\n\r\n`IServiceProvider.GetService` and `IAsyncServiceProvider.GetServiceAsync` may return null in any of several conditions, including:\r\n\r\n1. The service is not installed.\r\n2. The Package that proffers the service fails to initialize itself or the service.\r\n3. Visual Studio is running in \"safe mode\" and the package proffering the service is not allowed to load.\r\n4. Visual Studio is shutting down.\r\n\r\nMost of these conditions are *not* failures in the system but rather ordinary conditions that can occur that callers should be prepared for.\r\nAlways check the result of service queries before dereferencing those services.\r\nIf reduced functionality is an option when a service is absent, that is preferred.\r\nIf the service is mandatory for proper functioning of your feature, use `Assumes.Present<T>(T)` to check that the value is non-null and throw an informative exception if it is null.\r\nAlternatively, if throwing an exception in your context will lead to a product crash, display an error to the user and exit your feature.\r\n\r\nCrashing the product leads to data loss and/or the inability of the user to use other areas of the product. Deactivating your own feature when it does not have what it needs to run is therefore preferable.\r\n\r\n## Examples of patterns that are flagged by this analyzer\r\n\r\n```csharp\r\nclass MyCoolPackage : AsyncPackage\r\n{\r\n    public async Task InitializeAsync(/*...*/)\r\n    {\r\n        var bma = await this.GetServiceAsync(typeof(IVsBuildManagerAccessor));\r\n        bma.BeginDesignTimeBuild(); // warning reported here\r\n    }\r\n}\r\n```\r\n\r\n## Solution\r\n\r\nCheck for null first, using either `Assumes.Present` or an `if` check:\r\n\r\n```csharp\r\nusing Microsoft;\r\n\r\nclass MyCoolPackage : AsyncPackage\r\n{\r\n    public async Task InitializeAsync(/*...*/)\r\n    {\r\n        var bma = await this.GetServiceAsync(typeof(IVsBuildManagerAccessor));\r\n        Assumes.Present(bma);\r\n        bma.BeginDesignTimeBuild();\r\n    }\r\n}\r\n```\r\n\r\nor\r\n\r\n```csharp\r\nusing Microsoft;\r\n\r\nclass MyCoolPackage : AsyncPackage\r\n{\r\n    public async Task InitializeAsync(/*...*/)\r\n    {\r\n        var bma = await this.GetServiceAsync(typeof(IVsBuildManagerAccessor));\r\n        if (bma != null) {\r\n            bma.BeginDesignTimeBuild();\r\n        }\r\n    }\r\n}\r\n```\r\n\r\nCloses #63 "},"comment":{"url":"https://api.github.com/repos/Microsoft/VSSDK-Analyzers/issues/comments/397856475","html_url":"https://github.com/Microsoft/VSSDK-Analyzers/pull/68#issuecomment-397856475","issue_url":"https://api.github.com/repos/Microsoft/VSSDK-Analyzers/issues/68","id":397856475,"node_id":"MDEyOklzc3VlQ29tbWVudDM5Nzg1NjQ3NQ==","user":{"login":"AArnott","id":3548,"node_id":"MDQ6VXNlcjM1NDg=","avatar_url":"https://avatars2.githubusercontent.com/u/3548?v=4","gravatar_id":"","url":"https://api.github.com/users/AArnott","html_url":"https://github.com/AArnott","followers_url":"https://api.github.com/users/AArnott/followers","following_url":"https://api.github.com/users/AArnott/following{/other_user}","gists_url":"https://api.github.com/users/AArnott/gists{/gist_id}","starred_url":"https://api.github.com/users/AArnott/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AArnott/subscriptions","organizations_url":"https://api.github.com/users/AArnott/orgs","repos_url":"https://api.github.com/users/AArnott/repos","events_url":"https://api.github.com/users/AArnott/events{/privacy}","received_events_url":"https://api.github.com/users/AArnott/received_events","type":"User","site_admin":false},"created_at":"2018-06-17T05:47:43Z","updated_at":"2018-06-17T05:47:43Z","author_association":"MEMBER","body":"@jasonmal @heejaechang @jaredpar @sharwell This is something of a follow-up from our discussion on https://github.com/dotnet/roslyn/pull/26787 and what I've seen on many other PRs making a similar transition. I thought I'd mention you all here to vote for or against this. (I'm hoping you're for it, but it *was* an interesting discussion on your PR earlier)."}}
{"actor":{"display_login":"AArnott"}}