{"action":"created","issue":{"url":"https://api.github.com/repos/gbin/err/issues/478","labels_url":"https://api.github.com/repos/gbin/err/issues/478/labels{/name}","comments_url":"https://api.github.com/repos/gbin/err/issues/478/comments","events_url":"https://api.github.com/repos/gbin/err/issues/478/events","html_url":"https://github.com/gbin/err/issues/478","id":107656933,"number":478,"title":"BotPlugin should use composition instead of inheritance for storage.","user":{"login":"ascrane","id":1975643,"avatar_url":"https://avatars.githubusercontent.com/u/1975643?v=3","gravatar_id":"","url":"https://api.github.com/users/ascrane","html_url":"https://github.com/ascrane","followers_url":"https://api.github.com/users/ascrane/followers","following_url":"https://api.github.com/users/ascrane/following{/other_user}","gists_url":"https://api.github.com/users/ascrane/gists{/gist_id}","starred_url":"https://api.github.com/users/ascrane/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ascrane/subscriptions","organizations_url":"https://api.github.com/users/ascrane/orgs","repos_url":"https://api.github.com/users/ascrane/repos","events_url":"https://api.github.com/users/ascrane/events{/privacy}","received_events_url":"https://api.github.com/users/ascrane/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-09-22T06:59:13Z","updated_at":"2015-09-22T08:49:19Z","closed_at":null,"body":"Currently to implement a plugin, the `BotPlugin` class is extended and members registered with `@botcmd`. In turn, `BotPlugin` extends `StorageMixin` which is hard-coded to use `shelve` as its storage mechanism. This is very inconvenient for creating new storage implementations, as well as for testing — these dependencies should be parameterized and composed instead of inherited. This approach would allow me to easily drop in a [Redis Collection](https://redis-collections.readthedocs.org/en/latest/) as the storage mechanism, for instance, since it also supports a dict-like interface (`MutableMapping`). This would also easily support configurable storage backends based on a flag passed to the application.\r\n\r\nReally any dependencies should use this method but storage is the most obvious candidate right now."},"comment":{"url":"https://api.github.com/repos/gbin/err/issues/comments/142216590","html_url":"https://github.com/gbin/err/issues/478#issuecomment-142216590","issue_url":"https://api.github.com/repos/gbin/err/issues/478","id":142216590,"user":{"login":"ascrane","id":1975643,"avatar_url":"https://avatars.githubusercontent.com/u/1975643?v=3","gravatar_id":"","url":"https://api.github.com/users/ascrane","html_url":"https://github.com/ascrane","followers_url":"https://api.github.com/users/ascrane/followers","following_url":"https://api.github.com/users/ascrane/following{/other_user}","gists_url":"https://api.github.com/users/ascrane/gists{/gist_id}","starred_url":"https://api.github.com/users/ascrane/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ascrane/subscriptions","organizations_url":"https://api.github.com/users/ascrane/orgs","repos_url":"https://api.github.com/users/ascrane/repos","events_url":"https://api.github.com/users/ascrane/events{/privacy}","received_events_url":"https://api.github.com/users/ascrane/received_events","type":"User","site_admin":false},"created_at":"2015-09-22T08:49:19Z","updated_at":"2015-09-22T08:49:19Z","body":"The fact that storage is accessed by considering the Bot class itself a dictionary instead of using a dict-like member of the bot makes this not a trivial change (for seemingly no real convenience gain)."}}