{"id":13855943,"url":"https://github.com/phs/sauce","last_synced_at":"2025-07-13T16:30:52.297Z","repository":{"id":137507126,"uuid":"1607535","full_name":"phs/sauce","owner":"phs","description":"A C++98 Dependency Injection Framework MOVED TO GITLAB","archived":true,"fork":false,"pushed_at":"2017-04-02T03:54:45.000Z","size":28727,"stargazers_count":62,"open_issues_count":1,"forks_count":9,"subscribers_count":15,"default_branch":"master","last_synced_at":"2024-04-24T20:07:36.099Z","etag":null,"topics":["c-plus-plus","dependency-injection"],"latest_commit_sha":null,"homepage":"https://gitlab.com/philhsmith/sauce","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2011-04-13T03:29:26.000Z","updated_at":"2023-08-24T05:36:59.000Z","dependencies_parsed_at":"2023-03-22T12:03:15.172Z","dependency_job_id":null,"html_url":"https://github.com/phs/sauce","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phs%2Fsauce","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phs%2Fsauce/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phs%2Fsauce/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phs%2Fsauce/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phs","download_url":"https://codeload.github.com/phs/sauce/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":213987420,"owners_count":15666817,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-plus-plus","dependency-injection"],"created_at":"2024-08-05T02:00:58.570Z","updated_at":"2024-08-05T02:02:05.373Z","avatar_url":"https://github.com/phs.png","language":"HTML","funding_links":[],"categories":["TODO scan for Android support in followings"],"sub_categories":[],"readme":"# Sauce #\n\n[![Linux and OS X Build Status][travis-badge]][travis]\n\n[travis-badge]: https://travis-ci.org/phs/sauce.png?branch=master\n[travis]: https://travis-ci.org/phs/sauce\n\nA *C++98* dependency injection framework.\n\nIf you do not need strict C++98 compatibility, I suggest you look at Google's\n[fruit][google-fruit] instead.\n\nThe design and name are inspired by Google's excellent [Guice framework][google-guice],\nbut neither Google nor Guice is otherwise affiliated in any way.\n\n[google-guice]: https://github.com/google/guice\n[google-fruit]: https://github.com/google/fruit\n\n## The Gist ##\n\nI refer the reader to [Guice's documentation][guice-motivation] for an introduction to\ndependency injection as a concept, and why they might be interested in using it.\n\nIn Sauce, one defines _bindings_ that map interface types to implementation types.  Each\nbinding is declared in the context of a _module_ which is used to organize and refer to\ncollections of bindings at a time.  Modules may be function pointers, or classes\nproviding a certain `operator()`.  Groups of modules may be used together, to avoid\nduplicate bindings.\n\nAt runtime, one collects desired modules into a _modules_ object, which produces\n_injectors_.  One can then ask an injector to _provide_ a value (instance) of a desired\ntype (again supplied as a template parameter.)  When providing a value, implicit\ntransitive dependencies are provided as well.  All values are exchanged with shared\npointers (`(std|std::tr1|boost)::shared_ptr`s are supported) and the injector takes care\nof _disposing_ the value when the smart pointer deletes itself.\n\nRequesting the injector for an unbound type results in a runtime exception.  No RTTI is\nused (but we use a portable, homebrew version of same.)\n\nSauce is available with a liberal, BSD-ish [license][sauce-license].\n\n[guice-motivation]: https://github.com/google/guice/wiki/Motivation\n[sauce-license]: https://github.com/phs/sauce/blob/master/LICENSE\n\n## Hacking ##\n\nDevelopment that is not environment-specific is done with [vagrant][vagrant] over\n[virtualbox][virtualbox]:\n\n```bash\n$ vagrant up\n$ vagrant ssh\nvagrant@sauce:~$ cd sauce\nvagrant@sauce:~/sauce$ ./configure  # create make files\nvagrant@sauce:~/sauce$ make check   # compile and run unit tests\n```\n\n[vagrant]: http://www.vagrantup.com/\n[virtualbox]: https://www.virtualbox.org/\n\n## Scopes ##\n\nA side-effect of using an injector to hide implementation choices from dependents is the\ndiscouraged use of stack allocation and the `new` operator for dependencies.  The `new`\noperator (et. al.) has an additional guarantee past the ensuring the instance's concrete\ntype: the instance received is unique, and not shared.  This raises the question: will\nthe injector always provide new, successive instances, or will it ever reuse some?\n\nIt turns out the most useful answer is \"both\".  Depending on the context, it may be\nappropriate to always create new instances upon request, to always share a solitary\ninstance with everyone (such as in the [_Singleton_][singleton] pattern), or to do\nsomething in between.\n\nSauce supports _scopes_ to answer this need.  While within a scope, a participating\nbinding will only ever create a single instance of its bound type: if the dependency is\nprovided more than once, the same instance is reused.  One enters a scope with the\n`enter` method on the injector, to receive a _scoped_ injector.  Requests made to this\ninjector will benefit from the open scope.  To leave the scope, stop using the scoped\ninjector (either by simply dropping it on the floor, or by calling `exit` to recover the\noriginal.)  The injectors returned from `Modules` instances are created implicitly in\n`SingletonScope`, which can not be exited (at pain of runtime exception.)\n\nEntered scopes form a stack: entering the `RequestScope` from a `SessionScope` injector\nwill result in an injector that is within both scopes.  Put differently, such an injector\nwill try to provide both `RequestScope` and `SessionScope` dependencies from cache.  They\nare a stack in the sense that injectors beneath the top are guaranteed to survive those\nabove them.  It is illegal to reenter a scope already on the stack; a runtime exception\nis thrown.\n\nIt is possible (and encouraged!) to reenter a scope many times from a single injector in\n_parallel_.  For example, one may enter `RequestScope` from the same `SessionScope`\ninjector many times concurrently, to create many contemporary `RequestScope` injectors.\nThese will all cache `RequestScope` dependencies separately, but share the same\n`SessionScope` cache.  Such shared scopes are not thread-safe by default, but may be made\nso by supplying a locker type and a lockable instance when creating the initial, root\ninjector.  [Boost::thread][boost-thread]'s [`lock_guard`][boost-lock-guard] and\n[`mutex`][boost-mutex] are suitable for this purpose.\n\nSometimes it is convenient to force the creation of all dependencies up front in a given\nscope (such as singleton scope.)  This can help programs fail fast, by exposing\nenvironmental issues or other problems at start up.  Sauce supports this by optionally\n_eagerly injecting_ arbitrary scopes (with an injector method.)  One may only eagerly\ninject dependencies in open scopes.\n\nUnlike Guice, Sauce expects the developer to enter and eagerly inject scopes explicitly,\nat their convenience.  No entrance or eager injection occurs implicitly.\n\n[singleton]: http://en.wikipedia.org/wiki/Singleton_pattern\n[boost-thread]: http://www.boost.org/doc/libs/1_47_0/doc/html/thread.html\n[boost-lock-guard]: http://www.boost.org/doc/libs/1_47_0/doc/html/thread/synchronization.html#thread.synchronization.locks.lock_guard\n[boost-mutex]: http://www.boost.org/doc/libs/1_47_0/doc/html/thread/synchronization.html#thread.synchronization.mutex_types.mutex\n\n## Further Reading ##\n\n* [The \"Tutorial\" Test Suite](https://github.com/phs/sauce/blob/master/test/tutorial_test.cc)\n* [API Reference](http://phs.github.com/sauce/doxygen-doc/html/)\n\n## Wishlist ##\n\n* ~~Circular dependency detection~~\n* ~~Setter injection~~\n* ~~Named, overloaded bindings~~\n* ~~Eager-loaded singletons~~\n* ~~Injectable Providers for lazy resolution~~\n* Implicit bindings implied by integration within interfaces or implementations\n* ~~On-demand injection for provided instances~~\n* Member field injection (meh)\n* Static injection (meh)\n\n## Thanks ##\n\nThese peeps are amaze for helping make Sauce better!  Buy them all the drink of their\nchoice!\n\n* Casey B.\n* Jakub S.\n* Markus E.\n* [smithgeek](https://github.com/smithgeek)\n\n(If you're up here and want me to tweak/link, make a ticket or otherwise prod me.)\n\n## Copyright ##\n\nCopyright (c) 2011-2017 Phil Smith. See LICENSE for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphs%2Fsauce","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphs%2Fsauce","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphs%2Fsauce/lists"}