{"action":"created","comment":{"url":"https://api.github.com/repos/techtalk/SpecFlow/pulls/comments/31036565","id":31036565,"diff_hunk":"@@ -0,0 +1,108 @@\n+﻿using System;\n+using System.Collections;\n+using System.Collections.Generic;\n+using BoDi;\n+using System.Linq;\n+using TechTalk.SpecFlow.Assist;\n+using TechTalk.SpecFlow.Assist.ValueComparers;\n+using TechTalk.SpecFlow.Assist.ValueRetrievers;\n+\n+namespace TechTalk.SpecFlow.Assist\n+{\n+    public class Service\n+    {\n+\n+        private Dictionary<string, IValueComparer> _valueComparers = new Dictionary<string, IValueComparer>();\n+        private Dictionary<string, IValueRetriever> _valueRetrievers = new Dictionary<string, IValueRetriever>();\n+\n+        public static Service Instance { get; internal set; }\n+\n+        public IDictionary<string, IValueComparer> ValueComparers { get { return _valueComparers; } }\n+\n+        public IDictionary<string, IValueRetriever> ValueRetrievers { get { return _valueRetrievers; } }\n+\n+        public IDictionary<Type, Func<TableRow, Type, object>> ValueRetrieversByType {\n+            get {\n+\n+                var valueRetrievers = Container.Instance.Setup().ResolveAll<IValueRetriever>();\n+                var result = new Dictionary<Type, Func<TableRow, Type, object>>();\n+                foreach(var valueRetriever in valueRetrievers){\n+                    foreach(var type in valueRetriever.TypesForWhichIRetrieveValues()){\n+                        result[type] = (TableRow row, Type targetType) => valueRetriever.ExtractValueFromRow(row, targetType);\n+                    }\n+                }\n+                return result; \n+            }\n+        }\n+\n+        static Service()\n+        {\n+            Instance = new Service();\n+        }\n+\n+        public Service()\n+        {\n+            RegisterValueComparer(new DateTimeValueComparer(), \"datetime\");\n+            RegisterValueComparer(new BoolValueComparer(), \"bool\");\n+            RegisterValueComparer(new GuidValueComparer(new GuidValueRetriever()), \"guid\");\n+            RegisterValueComparer(new DecimalValueComparer(), \"decimal\");\n+            RegisterValueComparer(new DoubleValueComparer(), \"double\");\n+            RegisterValueComparer(new FloatValueComparer(), \"float\");\n+            RegisterValueComparer(new DefaultValueComparer(), \"default\");\n+\n+            RegisterValueRetriever(new StringValueRetriever(), \"vstring\");\n+            RegisterValueRetriever(new ByteValueRetriever(), \"vbyte\");\n+            RegisterValueRetriever(new SByteValueRetriever(), \"vsbyte\");\n+            RegisterValueRetriever(new IntValueRetriever(), \"vint\");\n+            RegisterValueRetriever(new UIntValueRetriever(), \"vuint\");\n+            RegisterValueRetriever(new ShortValueRetriever(), \"vshort\");\n+            RegisterValueRetriever(new UShortValueRetriever(), \"vushort\");\n+            RegisterValueRetriever(new LongValueRetriever(), \"vlong\");\n+            RegisterValueRetriever(new ULongValueRetriever(), \"vulong\");\n+            RegisterValueRetriever(new FloatValueRetriever(), \"vfloat\");\n+            RegisterValueRetriever(new DoubleValueRetriever(), \"vdouble\");\n+            RegisterValueRetriever(new DecimalValueRetriever(), \"vdecimal\");\n+            RegisterValueRetriever(new CharValueRetriever(), \"vchar\");\n+            RegisterValueRetriever(new BoolValueRetriever(), \"vbool\");\n+            RegisterValueRetriever(new DateTimeValueRetriever(), \"vdatetime\");\n+            RegisterValueRetriever(new GuidValueRetriever(), \"vguid\");\n+            RegisterValueRetriever(new EnumValueRetriever(), \"venum\");\n+            RegisterValueRetriever(new NullableGuidValueRetriever(), \"vnullableguid\");\n+            RegisterValueRetriever(new NullableDateTimeValueRetriever(), \"vnullabledatetime\");\n+            RegisterValueRetriever(new NullableBoolValueRetriever(), \"vnullablebool\");\n+            RegisterValueRetriever(new NullableCharValueRetriever(), \"vnullablechar\");\n+            RegisterValueRetriever(new NullableDecimalValueRetriever(), \"vnullabledecimal\");\n+            RegisterValueRetriever(new NullableDoubleValueRetriever(), \"vnullabledouble\");\n+            RegisterValueRetriever(new NullableFloatValueRetriever(), \"vnullablefloat\");\n+            RegisterValueRetriever(new NullableULongValueRetriever(), \"vnullableulong\");\n+            RegisterValueRetriever(new NullableByteValueRetriever(), \"vnullablebyte\");\n+            RegisterValueRetriever(new NullableSByteValueRetriever(), \"vnullablesbyte\");\n+            RegisterValueRetriever(new NullableIntValueRetriever(), \"vnullableint\");\n+            RegisterValueRetriever(new NullableUIntValueRetriever(), \"vnullableuint\");\n+            RegisterValueRetriever(new NullableShortValueRetriever(), \"vnullableshort\");\n+            RegisterValueRetriever(new NullableUShortValueRetriever(), \"vnullableushort\");\n+            RegisterValueRetriever(new NullableLongValueRetriever(), \"vnullablelong\");","path":"Runtime/Assist/Service.cs","position":87,"original_position":84,"commit_id":"c6521a61fdc16c49a91180530ca2066e0981f929","original_commit_id":"098036aaed9d087fafb3928ce491d65926608d4d","user":{"login":"darrencauthon","id":148768,"avatar_url":"https://avatars.githubusercontent.com/u/148768?v=3","gravatar_id":"","url":"https://api.github.com/users/darrencauthon","html_url":"https://github.com/darrencauthon","followers_url":"https://api.github.com/users/darrencauthon/followers","following_url":"https://api.github.com/users/darrencauthon/following{/other_user}","gists_url":"https://api.github.com/users/darrencauthon/gists{/gist_id}","starred_url":"https://api.github.com/users/darrencauthon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/darrencauthon/subscriptions","organizations_url":"https://api.github.com/users/darrencauthon/orgs","repos_url":"https://api.github.com/users/darrencauthon/repos","events_url":"https://api.github.com/users/darrencauthon/events{/privacy}","received_events_url":"https://api.github.com/users/darrencauthon/received_events","type":"User","site_admin":false},"body":"I'm going with (1)","created_at":"2015-05-26T14:11:02Z","updated_at":"2015-05-26T14:11:02Z","html_url":"https://github.com/techtalk/SpecFlow/pull/443#discussion_r31036565","pull_request_url":"https://api.github.com/repos/techtalk/SpecFlow/pulls/443","_links":{"self":{"href":"https://api.github.com/repos/techtalk/SpecFlow/pulls/comments/31036565"},"html":{"href":"https://github.com/techtalk/SpecFlow/pull/443#discussion_r31036565"},"pull_request":{"href":"https://api.github.com/repos/techtalk/SpecFlow/pulls/443"}}},"pull_request":{"url":"https://api.github.com/repos/techtalk/SpecFlow/pulls/443","id":35586746,"html_url":"https://github.com/techtalk/SpecFlow/pull/443","diff_url":"https://github.com/techtalk/SpecFlow/pull/443.diff","patch_url":"https://github.com/techtalk/SpecFlow/pull/443.patch","issue_url":"https://api.github.com/repos/techtalk/SpecFlow/issues/443","number":443,"state":"open","locked":false,"title":"Extendable Assist","user":{"login":"darrencauthon","id":148768,"avatar_url":"https://avatars.githubusercontent.com/u/148768?v=3","gravatar_id":"","url":"https://api.github.com/users/darrencauthon","html_url":"https://github.com/darrencauthon","followers_url":"https://api.github.com/users/darrencauthon/followers","following_url":"https://api.github.com/users/darrencauthon/following{/other_user}","gists_url":"https://api.github.com/users/darrencauthon/gists{/gist_id}","starred_url":"https://api.github.com/users/darrencauthon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/darrencauthon/subscriptions","organizations_url":"https://api.github.com/users/darrencauthon/orgs","repos_url":"https://api.github.com/users/darrencauthon/repos","events_url":"https://api.github.com/users/darrencauthon/events{/privacy}","received_events_url":"https://api.github.com/users/darrencauthon/received_events","type":"User","site_admin":false},"body":"WORK IN PROGRESS, do not merge.\r\n\r\nThis PR will allow SpecFlow users to register their own \"value retrievers\" and \"value comparers.\"\r\n\r\nWhat are those?  Bits that tell SpecFlow how to turn a string from a Gherkin table to a property, or how to compare them.\r\n\r\nLike this:\r\n\r\n```gherkin\r\n| First Name | Last Name |\r\n| John       | Galt      |\r\n```\r\n\r\n```c#\r\npublic class Person\r\n{\r\n    public string FirstName { get; set; }\r\n    public string LastName { get; set; }\r\n}\r\n\r\ntable.CreateInstance<Person>(); // will be a Person with FirstName = John, LastName = Galt\r\n```\r\n\r\nOut of the box, SpecFlow handles most of the default value types you'd find in C#.  But what if your object is something like this?\r\n\r\n```c#\r\npublic class Person\r\n{\r\n    public FancyString FirstName { get; set; }\r\n    public FancyString LastName { get; set; }\r\n}\r\n```\r\n\r\nOut of the box, SpecFlow will fail to bind \"John\" and \"Galt\" to FancyString.  But this PR will allow you to do something like this:\r\n\r\n```c#\r\nSpecFlow.Assist.Service.RegisterValueRetriever(new FancyStringValueRetriever(), \"fancy string retriever\");\r\nSpecFlow.Assist.Service.RegisterValueComparer(new FancyStringValueComparer(), \"fancy string comparer\"); \r\n```\r\n\r\nAnd presto-chango, now you can bind a value in a table to your custom object.","created_at":"2015-05-17T13:00:17Z","updated_at":"2015-05-26T14:11:02Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1a29ffba5db3f2c04b215e27c46993010b46dd6d","assignee":{"login":"darrencauthon","id":148768,"avatar_url":"https://avatars.githubusercontent.com/u/148768?v=3","gravatar_id":"","url":"https://api.github.com/users/darrencauthon","html_url":"https://github.com/darrencauthon","followers_url":"https://api.github.com/users/darrencauthon/followers","following_url":"https://api.github.com/users/darrencauthon/following{/other_user}","gists_url":"https://api.github.com/users/darrencauthon/gists{/gist_id}","starred_url":"https://api.github.com/users/darrencauthon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/darrencauthon/subscriptions","organizations_url":"https://api.github.com/users/darrencauthon/orgs","repos_url":"https://api.github.com/users/darrencauthon/repos","events_url":"https://api.github.com/users/darrencauthon/events{/privacy}","received_events_url":"https://api.github.com/users/darrencauthon/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/techtalk/SpecFlow/pulls/443/commits","review_comments_url":"https://api.github.com/repos/techtalk/SpecFlow/pulls/443/comments","review_comment_url":"https://api.github.com/repos/techtalk/SpecFlow/pulls/comments{/number}","comments_url":"https://api.github.com/repos/techtalk/SpecFlow/issues/443/comments","statuses_url":"https://api.github.com/repos/techtalk/SpecFlow/statuses/c6521a61fdc16c49a91180530ca2066e0981f929","head":{"label":"techtalk:extendable_value_handlers","ref":"extendable_value_handlers","sha":"c6521a61fdc16c49a91180530ca2066e0981f929","user":{"login":"techtalk","id":143350,"avatar_url":"https://avatars.githubusercontent.com/u/143350?v=3","gravatar_id":"","url":"https://api.github.com/users/techtalk","html_url":"https://github.com/techtalk","followers_url":"https://api.github.com/users/techtalk/followers","following_url":"https://api.github.com/users/techtalk/following{/other_user}","gists_url":"https://api.github.com/users/techtalk/gists{/gist_id}","starred_url":"https://api.github.com/users/techtalk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/techtalk/subscriptions","organizations_url":"https://api.github.com/users/techtalk/orgs","repos_url":"https://api.github.com/users/techtalk/repos","events_url":"https://api.github.com/users/techtalk/events{/privacy}","received_events_url":"https://api.github.com/users/techtalk/received_events","type":"User","site_admin":false},"repo":{"id":346594,"name":"SpecFlow","full_name":"techtalk/SpecFlow","owner":{"login":"techtalk","id":143350,"avatar_url":"https://avatars.githubusercontent.com/u/143350?v=3","gravatar_id":"","url":"https://api.github.com/users/techtalk","html_url":"https://github.com/techtalk","followers_url":"https://api.github.com/users/techtalk/followers","following_url":"https://api.github.com/users/techtalk/following{/other_user}","gists_url":"https://api.github.com/users/techtalk/gists{/gist_id}","starred_url":"https://api.github.com/users/techtalk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/techtalk/subscriptions","organizations_url":"https://api.github.com/users/techtalk/orgs","repos_url":"https://api.github.com/users/techtalk/repos","events_url":"https://api.github.com/users/techtalk/events{/privacy}","received_events_url":"https://api.github.com/users/techtalk/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/techtalk/SpecFlow","description":"Binding business requirements to .Net code","fork":false,"url":"https://api.github.com/repos/techtalk/SpecFlow","forks_url":"https://api.github.com/repos/techtalk/SpecFlow/forks","keys_url":"https://api.github.com/repos/techtalk/SpecFlow/keys{/key_id}","collaborators_url":"https://api.github.com/repos/techtalk/SpecFlow/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/techtalk/SpecFlow/teams","hooks_url":"https://api.github.com/repos/techtalk/SpecFlow/hooks","issue_events_url":"https://api.github.com/repos/techtalk/SpecFlow/issues/events{/number}","events_url":"https://api.github.com/repos/techtalk/SpecFlow/events","assignees_url":"https://api.github.com/repos/techtalk/SpecFlow/assignees{/user}","branches_url":"https://api.github.com/repos/techtalk/SpecFlow/branches{/branch}","tags_url":"https://api.github.com/repos/techtalk/SpecFlow/tags","blobs_url":"https://api.github.com/repos/techtalk/SpecFlow/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/techtalk/SpecFlow/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/techtalk/SpecFlow/git/refs{/sha}","trees_url":"https://api.github.com/repos/techtalk/SpecFlow/git/trees{/sha}","statuses_url":"https://api.github.com/repos/techtalk/SpecFlow/statuses/{sha}","languages_url":"https://api.github.com/repos/techtalk/SpecFlow/languages","stargazers_url":"https://api.github.com/repos/techtalk/SpecFlow/stargazers","contributors_url":"https://api.github.com/repos/techtalk/SpecFlow/contributors","subscribers_url":"https://api.github.com/repos/techtalk/SpecFlow/subscribers","subscription_url":"https://api.github.com/repos/techtalk/SpecFlow/subscription","commits_url":"https://api.github.com/repos/techtalk/SpecFlow/commits{/sha}","git_commits_url":"https://api.github.com/repos/techtalk/SpecFlow/git/commits{/sha}","comments_url":"https://api.github.com/repos/techtalk/SpecFlow/comments{/number}","issue_comment_url":"https://api.github.com/repos/techtalk/SpecFlow/issues/comments{/number}","contents_url":"https://api.github.com/repos/techtalk/SpecFlow/contents/{+path}","compare_url":"https://api.github.com/repos/techtalk/SpecFlow/compare/{base}...{head}","merges_url":"https://api.github.com/repos/techtalk/SpecFlow/merges","archive_url":"https://api.github.com/repos/techtalk/SpecFlow/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/techtalk/SpecFlow/downloads","issues_url":"https://api.github.com/repos/techtalk/SpecFlow/issues{/number}","pulls_url":"https://api.github.com/repos/techtalk/SpecFlow/pulls{/number}","milestones_url":"https://api.github.com/repos/techtalk/SpecFlow/milestones{/number}","notifications_url":"https://api.github.com/repos/techtalk/SpecFlow/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/techtalk/SpecFlow/labels{/name}","releases_url":"https://api.github.com/repos/techtalk/SpecFlow/releases{/id}","created_at":"2009-10-22T22:43:37Z","updated_at":"2015-05-14T17:46:46Z","pushed_at":"2015-05-26T14:10:33Z","git_url":"git://github.com/techtalk/SpecFlow.git","ssh_url":"git@github.com:techtalk/SpecFlow.git","clone_url":"https://github.com/techtalk/SpecFlow.git","svn_url":"https://github.com/techtalk/SpecFlow","homepage":"http://www.specflow.org/","size":124250,"stargazers_count":757,"watchers_count":757,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":310,"mirror_url":null,"open_issues_count":61,"forks":310,"open_issues":61,"watchers":757,"default_branch":"master"}},"base":{"label":"techtalk:v2","ref":"v2","sha":"97134d364e7e5b9f5529d68fd294a157c618f673","user":{"login":"techtalk","id":143350,"avatar_url":"https://avatars.githubusercontent.com/u/143350?v=3","gravatar_id":"","url":"https://api.github.com/users/techtalk","html_url":"https://github.com/techtalk","followers_url":"https://api.github.com/users/techtalk/followers","following_url":"https://api.github.com/users/techtalk/following{/other_user}","gists_url":"https://api.github.com/users/techtalk/gists{/gist_id}","starred_url":"https://api.github.com/users/techtalk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/techtalk/subscriptions","organizations_url":"https://api.github.com/users/techtalk/orgs","repos_url":"https://api.github.com/users/techtalk/repos","events_url":"https://api.github.com/users/techtalk/events{/privacy}","received_events_url":"https://api.github.com/users/techtalk/received_events","type":"User","site_admin":false},"repo":{"id":346594,"name":"SpecFlow","full_name":"techtalk/SpecFlow","owner":{"login":"techtalk","id":143350,"avatar_url":"https://avatars.githubusercontent.com/u/143350?v=3","gravatar_id":"","url":"https://api.github.com/users/techtalk","html_url":"https://github.com/techtalk","followers_url":"https://api.github.com/users/techtalk/followers","following_url":"https://api.github.com/users/techtalk/following{/other_user}","gists_url":"https://api.github.com/users/techtalk/gists{/gist_id}","starred_url":"https://api.github.com/users/techtalk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/techtalk/subscriptions","organizations_url":"https://api.github.com/users/techtalk/orgs","repos_url":"https://api.github.com/users/techtalk/repos","events_url":"https://api.github.com/users/techtalk/events{/privacy}","received_events_url":"https://api.github.com/users/techtalk/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/techtalk/SpecFlow","description":"Binding business requirements to .Net code","fork":false,"url":"https://api.github.com/repos/techtalk/SpecFlow","forks_url":"https://api.github.com/repos/techtalk/SpecFlow/forks","keys_url":"https://api.github.com/repos/techtalk/SpecFlow/keys{/key_id}","collaborators_url":"https://api.github.com/repos/techtalk/SpecFlow/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/techtalk/SpecFlow/teams","hooks_url":"https://api.github.com/repos/techtalk/SpecFlow/hooks","issue_events_url":"https://api.github.com/repos/techtalk/SpecFlow/issues/events{/number}","events_url":"https://api.github.com/repos/techtalk/SpecFlow/events","assignees_url":"https://api.github.com/repos/techtalk/SpecFlow/assignees{/user}","branches_url":"https://api.github.com/repos/techtalk/SpecFlow/branches{/branch}","tags_url":"https://api.github.com/repos/techtalk/SpecFlow/tags","blobs_url":"https://api.github.com/repos/techtalk/SpecFlow/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/techtalk/SpecFlow/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/techtalk/SpecFlow/git/refs{/sha}","trees_url":"https://api.github.com/repos/techtalk/SpecFlow/git/trees{/sha}","statuses_url":"https://api.github.com/repos/techtalk/SpecFlow/statuses/{sha}","languages_url":"https://api.github.com/repos/techtalk/SpecFlow/languages","stargazers_url":"https://api.github.com/repos/techtalk/SpecFlow/stargazers","contributors_url":"https://api.github.com/repos/techtalk/SpecFlow/contributors","subscribers_url":"https://api.github.com/repos/techtalk/SpecFlow/subscribers","subscription_url":"https://api.github.com/repos/techtalk/SpecFlow/subscription","commits_url":"https://api.github.com/repos/techtalk/SpecFlow/commits{/sha}","git_commits_url":"https://api.github.com/repos/techtalk/SpecFlow/git/commits{/sha}","comments_url":"https://api.github.com/repos/techtalk/SpecFlow/comments{/number}","issue_comment_url":"https://api.github.com/repos/techtalk/SpecFlow/issues/comments{/number}","contents_url":"https://api.github.com/repos/techtalk/SpecFlow/contents/{+path}","compare_url":"https://api.github.com/repos/techtalk/SpecFlow/compare/{base}...{head}","merges_url":"https://api.github.com/repos/techtalk/SpecFlow/merges","archive_url":"https://api.github.com/repos/techtalk/SpecFlow/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/techtalk/SpecFlow/downloads","issues_url":"https://api.github.com/repos/techtalk/SpecFlow/issues{/number}","pulls_url":"https://api.github.com/repos/techtalk/SpecFlow/pulls{/number}","milestones_url":"https://api.github.com/repos/techtalk/SpecFlow/milestones{/number}","notifications_url":"https://api.github.com/repos/techtalk/SpecFlow/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/techtalk/SpecFlow/labels{/name}","releases_url":"https://api.github.com/repos/techtalk/SpecFlow/releases{/id}","created_at":"2009-10-22T22:43:37Z","updated_at":"2015-05-14T17:46:46Z","pushed_at":"2015-05-26T14:10:33Z","git_url":"git://github.com/techtalk/SpecFlow.git","ssh_url":"git@github.com:techtalk/SpecFlow.git","clone_url":"https://github.com/techtalk/SpecFlow.git","svn_url":"https://github.com/techtalk/SpecFlow","homepage":"http://www.specflow.org/","size":124250,"stargazers_count":757,"watchers_count":757,"language":"C++","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":310,"mirror_url":null,"open_issues_count":61,"forks":310,"open_issues":61,"watchers":757,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/techtalk/SpecFlow/pulls/443"},"html":{"href":"https://github.com/techtalk/SpecFlow/pull/443"},"issue":{"href":"https://api.github.com/repos/techtalk/SpecFlow/issues/443"},"comments":{"href":"https://api.github.com/repos/techtalk/SpecFlow/issues/443/comments"},"review_comments":{"href":"https://api.github.com/repos/techtalk/SpecFlow/pulls/443/comments"},"review_comment":{"href":"https://api.github.com/repos/techtalk/SpecFlow/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/techtalk/SpecFlow/pulls/443/commits"},"statuses":{"href":"https://api.github.com/repos/techtalk/SpecFlow/statuses/c6521a61fdc16c49a91180530ca2066e0981f929"}}}}