{"action":"created","comment":{"url":"https://api.github.com/repos/nunit/nunit/pulls/comments/37664203","id":37664203,"diff_hunk":"@@ -0,0 +1,154 @@\n+﻿// ***********************************************************************\n+// Copyright (c) 2015 Charlie Poole\n+//\n+// Permission is hereby granted, free of charge, to any person obtaining\n+// a copy of this software and associated documentation files (the\n+// \"Software\"), to deal in the Software without restriction, including\n+// without limitation the rights to use, copy, modify, merge, publish,\n+// distribute, sublicense, and/or sell copies of the Software, and to\n+// permit persons to whom the Software is furnished to do so, subject to\n+// the following conditions:\n+// \n+// The above copyright notice and this permission notice shall be\n+// included in all copies or substantial portions of the Software.\n+// \n+// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n+// ***********************************************************************\n+\n+using System;\n+using System.Collections.Generic;\n+using System.IO;\n+using System.Reflection;\n+using System.Xml;\n+using Mono.Cecil;\n+using NUnit.Engine.Extensibility;\n+using NUnit.Engine.Internal;\n+\n+namespace NUnit.Engine.Services\n+{\n+    public class ExtensionService : Service\n+    {\n+        private List<ExtensionPoint> _extensionPoints = new List<ExtensionPoint>();\n+        private Dictionary<string, ExtensionPoint> _pathIndex = new Dictionary<string, ExtensionPoint>();\n+        private Dictionary<Type, ExtensionPoint> _typeIndex = new Dictionary<Type, ExtensionPoint>();\n+\n+        private List<ExtensionNode> _extensions = new List<ExtensionNode>();\n+\n+        #region Public Properties\n+\n+        public IEnumerable<ExtensionPoint> ExtensionPoints\n+        {\n+            get { return _extensionPoints; }\n+        }\n+\n+        public IEnumerable<ExtensionNode> Extensions\n+        {\n+            get { return _extensions;  }\n+        }\n+\n+        #endregion\n+\n+        public ExtensionPoint GetExtensionPoint(string path)","path":"src/NUnitEngine/nunit.engine/Services/ExtensionService.cs","position":57,"original_position":57,"commit_id":"4d56a82e985cdad89deba7114dca52f35211c4fc","original_commit_id":"4d56a82e985cdad89deba7114dca52f35211c4fc","user":{"login":"CharliePoole","id":2678661,"avatar_url":"https://avatars.githubusercontent.com/u/2678661?v=3","gravatar_id":"","url":"https://api.github.com/users/CharliePoole","html_url":"https://github.com/CharliePoole","followers_url":"https://api.github.com/users/CharliePoole/followers","following_url":"https://api.github.com/users/CharliePoole/following{/other_user}","gists_url":"https://api.github.com/users/CharliePoole/gists{/gist_id}","starred_url":"https://api.github.com/users/CharliePoole/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CharliePoole/subscriptions","organizations_url":"https://api.github.com/users/CharliePoole/orgs","repos_url":"https://api.github.com/users/CharliePoole/repos","events_url":"https://api.github.com/users/CharliePoole/events{/privacy}","received_events_url":"https://api.github.com/users/CharliePoole/received_events","type":"User","site_admin":false},"body":"It's more advance engineering than I usually do, for sure. But that comes from working on something that shouldn't be changed once implemented. Or at least not changed in a breaking way.\r\n\r\nNote that the rule would not be simply \"Every extension point needs to expect a unique interface.\" To that, you have to add the rule \"An extension must implement the interface required by it's extension point an may not implement any interface required by any **other** extension point.\" It seems to me that this puts an extreme burden on the authors of extensions, who can't really know what other extension points may be available in a given system. \r\n\r\nThat said, I'll do some more work on this to see what I can come up with.","created_at":"2015-08-21T18:36:24Z","updated_at":"2015-08-21T18:36:24Z","html_url":"https://github.com/nunit/nunit/pull/774#discussion_r37664203","pull_request_url":"https://api.github.com/repos/nunit/nunit/pulls/774","_links":{"self":{"href":"https://api.github.com/repos/nunit/nunit/pulls/comments/37664203"},"html":{"href":"https://github.com/nunit/nunit/pull/774#discussion_r37664203"},"pull_request":{"href":"https://api.github.com/repos/nunit/nunit/pulls/774"}}},"pull_request":{"url":"https://api.github.com/repos/nunit/nunit/pulls/774","id":42506180,"html_url":"https://github.com/nunit/nunit/pull/774","diff_url":"https://github.com/nunit/nunit/pull/774.diff","patch_url":"https://github.com/nunit/nunit/pull/774.patch","issue_url":"https://api.github.com/repos/nunit/nunit/issues/774","number":774,"state":"open","locked":false,"title":"Replace Mono.Addins with our own addin implementation","user":{"login":"CharliePoole","id":2678661,"avatar_url":"https://avatars.githubusercontent.com/u/2678661?v=3","gravatar_id":"","url":"https://api.github.com/users/CharliePoole","html_url":"https://github.com/CharliePoole","followers_url":"https://api.github.com/users/CharliePoole/followers","following_url":"https://api.github.com/users/CharliePoole/following{/other_user}","gists_url":"https://api.github.com/users/CharliePoole/gists{/gist_id}","starred_url":"https://api.github.com/users/CharliePoole/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CharliePoole/subscriptions","organizations_url":"https://api.github.com/users/CharliePoole/orgs","repos_url":"https://api.github.com/users/CharliePoole/repos","events_url":"https://api.github.com/users/CharliePoole/events{/privacy}","received_events_url":"https://api.github.com/users/CharliePoole/received_events","type":"User","site_admin":false},"body":"** Now Ready to Review and Merge**\r\n\r\nI'm creating this PR as I _begin_ work on issue #749, rather than at the end, so that we can use it as a place to discuss how we want our addins to work as well as for normal code review.\r\n\r\nThe initial commit simply hides all interaction with Mono.Addins behind a new service, which I called ExtensionService - not very original I suppose.\r\n\r\nI have also created a rough spec for this implementation, which you can find here:\r\n    https://github.com/nunit/dev/wiki/Engine-Addins\r\n\r\nLet's have any discussion of either the spec or the code right on this PR.","created_at":"2015-08-14T23:08:00Z","updated_at":"2015-08-21T18:36:24Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4081943896e79c34fcef6e730449d504b8cc97d9","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/nunit/nunit/pulls/774/commits","review_comments_url":"https://api.github.com/repos/nunit/nunit/pulls/774/comments","review_comment_url":"https://api.github.com/repos/nunit/nunit/pulls/comments{/number}","comments_url":"https://api.github.com/repos/nunit/nunit/issues/774/comments","statuses_url":"https://api.github.com/repos/nunit/nunit/statuses/4d56a82e985cdad89deba7114dca52f35211c4fc","head":{"label":"nunit:issue-749","ref":"issue-749","sha":"4d56a82e985cdad89deba7114dca52f35211c4fc","user":{"login":"nunit","id":2678858,"avatar_url":"https://avatars.githubusercontent.com/u/2678858?v=3","gravatar_id":"","url":"https://api.github.com/users/nunit","html_url":"https://github.com/nunit","followers_url":"https://api.github.com/users/nunit/followers","following_url":"https://api.github.com/users/nunit/following{/other_user}","gists_url":"https://api.github.com/users/nunit/gists{/gist_id}","starred_url":"https://api.github.com/users/nunit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nunit/subscriptions","organizations_url":"https://api.github.com/users/nunit/orgs","repos_url":"https://api.github.com/users/nunit/repos","events_url":"https://api.github.com/users/nunit/events{/privacy}","received_events_url":"https://api.github.com/users/nunit/received_events","type":"Organization","site_admin":false},"repo":{"id":13692183,"name":"nunit","full_name":"nunit/nunit","owner":{"login":"nunit","id":2678858,"avatar_url":"https://avatars.githubusercontent.com/u/2678858?v=3","gravatar_id":"","url":"https://api.github.com/users/nunit","html_url":"https://github.com/nunit","followers_url":"https://api.github.com/users/nunit/followers","following_url":"https://api.github.com/users/nunit/following{/other_user}","gists_url":"https://api.github.com/users/nunit/gists{/gist_id}","starred_url":"https://api.github.com/users/nunit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nunit/subscriptions","organizations_url":"https://api.github.com/users/nunit/orgs","repos_url":"https://api.github.com/users/nunit/repos","events_url":"https://api.github.com/users/nunit/events{/privacy}","received_events_url":"https://api.github.com/users/nunit/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nunit/nunit","description":"NUnit 3.0 framework, engine and console runner","fork":false,"url":"https://api.github.com/repos/nunit/nunit","forks_url":"https://api.github.com/repos/nunit/nunit/forks","keys_url":"https://api.github.com/repos/nunit/nunit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nunit/nunit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nunit/nunit/teams","hooks_url":"https://api.github.com/repos/nunit/nunit/hooks","issue_events_url":"https://api.github.com/repos/nunit/nunit/issues/events{/number}","events_url":"https://api.github.com/repos/nunit/nunit/events","assignees_url":"https://api.github.com/repos/nunit/nunit/assignees{/user}","branches_url":"https://api.github.com/repos/nunit/nunit/branches{/branch}","tags_url":"https://api.github.com/repos/nunit/nunit/tags","blobs_url":"https://api.github.com/repos/nunit/nunit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nunit/nunit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nunit/nunit/git/refs{/sha}","trees_url":"https://api.github.com/repos/nunit/nunit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nunit/nunit/statuses/{sha}","languages_url":"https://api.github.com/repos/nunit/nunit/languages","stargazers_url":"https://api.github.com/repos/nunit/nunit/stargazers","contributors_url":"https://api.github.com/repos/nunit/nunit/contributors","subscribers_url":"https://api.github.com/repos/nunit/nunit/subscribers","subscription_url":"https://api.github.com/repos/nunit/nunit/subscription","commits_url":"https://api.github.com/repos/nunit/nunit/commits{/sha}","git_commits_url":"https://api.github.com/repos/nunit/nunit/git/commits{/sha}","comments_url":"https://api.github.com/repos/nunit/nunit/comments{/number}","issue_comment_url":"https://api.github.com/repos/nunit/nunit/issues/comments{/number}","contents_url":"https://api.github.com/repos/nunit/nunit/contents/{+path}","compare_url":"https://api.github.com/repos/nunit/nunit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nunit/nunit/merges","archive_url":"https://api.github.com/repos/nunit/nunit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nunit/nunit/downloads","issues_url":"https://api.github.com/repos/nunit/nunit/issues{/number}","pulls_url":"https://api.github.com/repos/nunit/nunit/pulls{/number}","milestones_url":"https://api.github.com/repos/nunit/nunit/milestones{/number}","notifications_url":"https://api.github.com/repos/nunit/nunit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nunit/nunit/labels{/name}","releases_url":"https://api.github.com/repos/nunit/nunit/releases{/id}","created_at":"2013-10-18T23:43:29Z","updated_at":"2015-08-20T15:21:14Z","pushed_at":"2015-08-21T16:56:08Z","git_url":"git://github.com/nunit/nunit.git","ssh_url":"git@github.com:nunit/nunit.git","clone_url":"https://github.com/nunit/nunit.git","svn_url":"https://github.com/nunit/nunit","homepage":"http://www.nunit.org/","size":40362,"stargazers_count":313,"watchers_count":313,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":140,"mirror_url":null,"open_issues_count":146,"forks":140,"open_issues":146,"watchers":313,"default_branch":"master"}},"base":{"label":"nunit:master","ref":"master","sha":"73d2591d7b58ca317695eb276a50ee751cd229df","user":{"login":"nunit","id":2678858,"avatar_url":"https://avatars.githubusercontent.com/u/2678858?v=3","gravatar_id":"","url":"https://api.github.com/users/nunit","html_url":"https://github.com/nunit","followers_url":"https://api.github.com/users/nunit/followers","following_url":"https://api.github.com/users/nunit/following{/other_user}","gists_url":"https://api.github.com/users/nunit/gists{/gist_id}","starred_url":"https://api.github.com/users/nunit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nunit/subscriptions","organizations_url":"https://api.github.com/users/nunit/orgs","repos_url":"https://api.github.com/users/nunit/repos","events_url":"https://api.github.com/users/nunit/events{/privacy}","received_events_url":"https://api.github.com/users/nunit/received_events","type":"Organization","site_admin":false},"repo":{"id":13692183,"name":"nunit","full_name":"nunit/nunit","owner":{"login":"nunit","id":2678858,"avatar_url":"https://avatars.githubusercontent.com/u/2678858?v=3","gravatar_id":"","url":"https://api.github.com/users/nunit","html_url":"https://github.com/nunit","followers_url":"https://api.github.com/users/nunit/followers","following_url":"https://api.github.com/users/nunit/following{/other_user}","gists_url":"https://api.github.com/users/nunit/gists{/gist_id}","starred_url":"https://api.github.com/users/nunit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nunit/subscriptions","organizations_url":"https://api.github.com/users/nunit/orgs","repos_url":"https://api.github.com/users/nunit/repos","events_url":"https://api.github.com/users/nunit/events{/privacy}","received_events_url":"https://api.github.com/users/nunit/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nunit/nunit","description":"NUnit 3.0 framework, engine and console runner","fork":false,"url":"https://api.github.com/repos/nunit/nunit","forks_url":"https://api.github.com/repos/nunit/nunit/forks","keys_url":"https://api.github.com/repos/nunit/nunit/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nunit/nunit/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nunit/nunit/teams","hooks_url":"https://api.github.com/repos/nunit/nunit/hooks","issue_events_url":"https://api.github.com/repos/nunit/nunit/issues/events{/number}","events_url":"https://api.github.com/repos/nunit/nunit/events","assignees_url":"https://api.github.com/repos/nunit/nunit/assignees{/user}","branches_url":"https://api.github.com/repos/nunit/nunit/branches{/branch}","tags_url":"https://api.github.com/repos/nunit/nunit/tags","blobs_url":"https://api.github.com/repos/nunit/nunit/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nunit/nunit/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nunit/nunit/git/refs{/sha}","trees_url":"https://api.github.com/repos/nunit/nunit/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nunit/nunit/statuses/{sha}","languages_url":"https://api.github.com/repos/nunit/nunit/languages","stargazers_url":"https://api.github.com/repos/nunit/nunit/stargazers","contributors_url":"https://api.github.com/repos/nunit/nunit/contributors","subscribers_url":"https://api.github.com/repos/nunit/nunit/subscribers","subscription_url":"https://api.github.com/repos/nunit/nunit/subscription","commits_url":"https://api.github.com/repos/nunit/nunit/commits{/sha}","git_commits_url":"https://api.github.com/repos/nunit/nunit/git/commits{/sha}","comments_url":"https://api.github.com/repos/nunit/nunit/comments{/number}","issue_comment_url":"https://api.github.com/repos/nunit/nunit/issues/comments{/number}","contents_url":"https://api.github.com/repos/nunit/nunit/contents/{+path}","compare_url":"https://api.github.com/repos/nunit/nunit/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nunit/nunit/merges","archive_url":"https://api.github.com/repos/nunit/nunit/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nunit/nunit/downloads","issues_url":"https://api.github.com/repos/nunit/nunit/issues{/number}","pulls_url":"https://api.github.com/repos/nunit/nunit/pulls{/number}","milestones_url":"https://api.github.com/repos/nunit/nunit/milestones{/number}","notifications_url":"https://api.github.com/repos/nunit/nunit/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nunit/nunit/labels{/name}","releases_url":"https://api.github.com/repos/nunit/nunit/releases{/id}","created_at":"2013-10-18T23:43:29Z","updated_at":"2015-08-20T15:21:14Z","pushed_at":"2015-08-21T16:56:08Z","git_url":"git://github.com/nunit/nunit.git","ssh_url":"git@github.com:nunit/nunit.git","clone_url":"https://github.com/nunit/nunit.git","svn_url":"https://github.com/nunit/nunit","homepage":"http://www.nunit.org/","size":40362,"stargazers_count":313,"watchers_count":313,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":140,"mirror_url":null,"open_issues_count":146,"forks":140,"open_issues":146,"watchers":313,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/nunit/nunit/pulls/774"},"html":{"href":"https://github.com/nunit/nunit/pull/774"},"issue":{"href":"https://api.github.com/repos/nunit/nunit/issues/774"},"comments":{"href":"https://api.github.com/repos/nunit/nunit/issues/774/comments"},"review_comments":{"href":"https://api.github.com/repos/nunit/nunit/pulls/774/comments"},"review_comment":{"href":"https://api.github.com/repos/nunit/nunit/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/nunit/nunit/pulls/774/commits"},"statuses":{"href":"https://api.github.com/repos/nunit/nunit/statuses/4d56a82e985cdad89deba7114dca52f35211c4fc"}}}}