{"id":29623835,"url":"https://github.com/mikemitterer/dryice","last_synced_at":"2025-10-18T07:52:08.321Z","repository":{"id":56828242,"uuid":"126786029","full_name":"MikeMitterer/dryice","owner":"MikeMitterer","description":"Dependency injection framework for Dart","archived":false,"fork":false,"pushed_at":"2020-09-30T17:39:48.000Z","size":172,"stargazers_count":15,"open_issues_count":3,"forks_count":6,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-16T06:44:27.991Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Dart","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/MikeMitterer.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-03-26T06:51:43.000Z","updated_at":"2022-12-01T05:14:14.000Z","dependencies_parsed_at":"2022-08-29T02:40:51.863Z","dependency_job_id":null,"html_url":"https://github.com/MikeMitterer/dryice","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/MikeMitterer/dryice","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikeMitterer%2Fdryice","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikeMitterer%2Fdryice/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikeMitterer%2Fdryice/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikeMitterer%2Fdryice/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MikeMitterer","download_url":"https://codeload.github.com/MikeMitterer/dryice/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikeMitterer%2Fdryice/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266242072,"owners_count":23898102,"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":[],"created_at":"2025-07-21T05:08:10.430Z","updated_at":"2025-10-18T07:52:03.264Z","avatar_url":"https://github.com/MikeMitterer.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DryIce (built mirrors / reflectable)\n\u003e Lightweight dependency injection framework for Dart. No need for mirrors!\n\n## Getting Started\nDryIce consists of two parts.\n * **Modules** containing your class registrations.\n * **Injectors** that uses the **Module** to inject instances into your code.\n\nThe following example should get you started:\n\n**1.** Add *DryIce* to your **pubspec.yaml** and run **pub install**\n```yaml\ndependencies:\n   dryice: any\n```\n\n**2.** Create some classes and interfaces to inject\n```dart\n@injectable\nabstract class BillingService {\n    Receipt chargeOrder(Order order, CreditCard creditCard);\n}\n\n@injectable\nclass BillingServiceImpl implements BillingService {\n  @inject\n  CreditProcessor _processor;\n\n  Receipt chargeOrder(Order order, CreditCard creditCard) {\n    if(!_processor.validate(creditCard)) {\n      throw new ArgumentError(\"payment method not accepted\");\n    }\n    // :\n  }\n}\n```\n\n**3.** Register types and classes in a module\n```dart\nclass ExampleModule extends Module {\n\n  @override\n  configure() {\n    // register [CreditProcessor] as a singleton\n    bind(CreditProcessor).to(CreditProcessorImpl).asSingleton();\n\n    // register [BillingService] so a new version is created each time its requested\n    bind(BillingService).toType(BillingServiceImpl);\n  }\n}\n```\n\n**4.** Run it\n\n```dart\nimport \"package:dryice/dryice.dart\";\n\n// This is the file that gets created\n// if you run 'pub run build_runner build'\nimport 'main.reflectable.dart';\n\nmain() {\n    initializeReflectable();\n\n\tfinal injector = new Injector(new ExampleModule());\n\tfinal billingService = injector.getInstance(BillingService);\n\tfinal creditCard = new CreditCard(\"VISA\");\n\tfinal order = new Order(\"Dart: Up and Running\");\n\t\n\tbillingService.chargeOrder(order, creditCard);\n}\n```\n\nfor more information see the full example [here](samples/cmdline/app/example_app.dart).\n\n## Dependency Injection with DryIce\n\nYou can use the **@injectable** annotation to mark classes as **injectable**,\nuse **@inject** annotation to mark objects, functions and constructors for injection the following ways:\n(It is not necessary to mark a default constructor with **@inject** - only complex CTORs must be marked)\n\n * Injection of public and private fields (object/instance variables)\n```dart\n@injectable\nclass MyOtherClass {\n  @inject\n  SomeClass field;\n\n  @inject\n  SomeOtherClass _privateField;\n}\n```\n\n * Injection of constructor parameters\n```dart\n@injectable\nclass MyClass {\n  @inject\n  MyClass(this.field);\n\n  MyOtherClass field;\n}\n```\n\n * Injection of public and private setters\n```dart\n@injectable\nclass SomeClass {\n  @inject\n  set value(SomeOtherClass val) =\u003e _privateValue = val;\n\n  @inject\n  set _value(SomeOtherClass val) =\u003e _anotherPrivateValue = val;\n\n  SomeOtherClass _privateValue, _anotherPrivateValue;\n}\n```\n\nThe injected objects are configured either by extending the **Module** class and using one of\nits *bind* functions or directly on the **Injector**.\n\n * register type **MyType**.\n```dart\nbind(MyType)\n```\n\n * register interface **MyType** to a class implementing it.\n```dart\nbind(MyType).toType(MyTypeImpl)\n```\n\n * register a singleton\n```dart\nbind(MyType).to(MySuperType).asSingleton();\n```\n\n * register type **MyType** to existing object (another way for singleton injections)\n```dart\nbind(MyType).toInstance(object)\n```\n\n * register a **typedef** to a function matching it.\n```dart\nbind(MyTypedef).toFunction(function)\n```\n\n * register **MyType** to function that can build instances of it\n```dart\nbind(MyType).toBuilder(() =\u003e new MyType())\n```\n\n * use Module to install other modules configuration\n```dart\nclass MyApplicationModule extends Module {\n  @override\n  configure() {\n    install(new ComponentModule());\n\n    bind(Emailer).to(EmailerToGMX).asSingleton();\n  }\n}\n```\n\n## Named Injections\nDryIce supports named injections by using the **@Named** annotation. Currently this annotation\nworks everywhere the **@inject** annotation works.\n\n```dart\nclass MyClass {\n  @inject\n  @Named('my-special-implementation')\n  SomeClass _someClass;\n}\n```\n\nThe configuration is as before except you now provide an additional **name** paramater.\n\n```dart\nbind(MyType, named: \"my-name\").toType(MyTypeImpl)\n```\n\nThe configuration is as before except you now provide an additional **name** paramater.\n\n## Annotated (typed) Injections\nYou can also use other classes for annotation.\nworks everywhere the **@inject** annotation works.\n\n```dart\n@injectable\nclass UrlGoogle { const UrlGoogle(); }\n\n@injectable\nclass UrlFacebook { const UrlFacebook(); }\n\nclass MyModule extends Module {\n  @override\n  configure() {\n    // annotated\n    bind(String,annotatedWith: UrlGoogle ).toInstance(\"http://www.google.com/\");\n    bind(String,annotatedWith: UrlFacebook ).toInstance(\"http://www.facebook.com/\");\n  }\n}\n\n@injectable\nclass MyClass {\n  @inject\n  @UrlGoogle()\n  String url;\n}\n```\n\nThe configuration is as before except you now provide an additional **annotation**.\n\n\n## Advanced Features\n * **Get instances directly** Instead of using the **@inject** annotation to resolve injections you\n can use the injectors **getInstance** method.\n```dart\nMyClass instance = injector.getInstance(MyClass);\n```\n\n * **Get named instances directly** Instead of using the **@Named** annotation to resolve named\n injections you can use the injectors **getInstance** method with its **named** parameter.\n```dart\nMyType instance = injector.getInstance(MyType, named: \"my-name\");\n```\n\n * **Get annotated instances directly** Instead of using the appropriate annotation to resolve\n annotated injections you can use the injectors **getInstance** method with its **annotatedWith** parameter.\n```dart\nString url = injector.getInstance(MyType, annotatedWith: UrlGoogle);\n```\n\n * **To register and resole configuration values** You can use named or annotated registrations\n to inject configuration values into your application.\n```dart\nclass TestModule extends Module {\n  configure() {\n\t\tbind(String, named: \"web-service-host\").toInstace(\"http://test-service.name\");\n\t\tbind(String, annotatedWith: UrlGoogle ).toInstance(\"http://www.google.com/\");\n\t}\n}\n\n// application code\nString get webServiceHost =\u003e injector.getInstance(String, named: \"web-service-host\");\nString get webServiceHost2 =\u003e injector.getInstance(String, annotatedWith: UrlGoogle);\n```\n\n * **Constructor injection**\nDryIce also support constructors with optional params.\n\n```dart\n@injectable\nclass MyClass {\n  String getName() =\u003e \"MyClass\";\n}\n\n@injectable\nclass CTOROptionalInjection extends MyClass {\n  final String url;\n  final String lang;\n\n  @inject\n  CTOROptionalInjection(@UrlGoogle() final String this.url,[ final String language ])\n      : lang = language ?? \"C++\";\n\n  @override\n  String getName() =\u003e \"CTORInjection - $url ($lang)\";\n}\n\nfinal injector = new Injector()\n  ..bind(String,annotatedWith: UrlGoogle ).toInstance(\"http://www.google.com/\")\n  ..bind(MyClass).toType(CTOROptionalInjection)\n;\nfinal MyClass mc = injector.getInstance(MyClass);\n```\n\n * **Registering dependencies at runtime** You can bind dependencies at runtime directly on the **Injector**.\n```dart\n injector.bind(User).toInstance(user);\n var user = injector.getInstance(User);\n```\n\n * **Unregistering dependencies at runtime** You can unregister dependencies at runtime using the **unregister** method on the **Injector**.\n```dart\ninjector.unregister(User);\n```\n\n * **Using multiple modules** You can compose modules using the **Injector.fromModules** constructor.\n```dart\nclass MyModule extends Module {\n  \tconfigure() {\n\t\tregister(MyClass).toType(MyClass);\n\t}\n}\n\nclass YourModule extends Module {\n  \tconfigure() {\n\t\tregister(YourClass).toType(YourClass);\n\t}\n}\n\nvar injector = new Injector.fromModules([new MyModule(), new YourModule()]);\nvar myClass = injector.getInstance(MyClass);\nvar yourClass = injector.getInstance(YourClass);\n```\n\n * **Install other modules within main module**\n\n```dart\nclass MyModule extends Module {\n  \tconfigure() {\n\t\tregister(MyClass).toType(MyClass);\n\t}\n}\n\nclass MyMainModule extends Module {\n  \tconfigure() {\n  \t    install(new MyModule());\n\t\tregister(YourClass).toType(YourClass);\n\t}\n}\n\nvar injector = new Injector( new MyMainModule());\nvar myClass = injector.getInstance(MyClass);\nvar yourClass = injector.getInstance(YourClass);\n```\n\n * **Joining injectors** You can join multiple injector instances to one using the **Injector.fromInjectors** constructor.\n```dart\nvar myInjector = new Injector();\nmyInjector.register(MyClass).toType(MyClass);\n\nvar yourInjector = new Injector();\nyourInjector.register(YourClass).toType(YourClass);\n\nvar injector = new Injector.fromInjectors([myInjector, yourInjector]);\nvar myClass = injector.getInstance(MyClass);\nvar yourClass = injector.getInstance(YourClass);\n```\n\n## Compatibility / migration from di:package\n\nTo make migration easier we provide the following functions:\n\n * `Injector.bind` is the same as `Injector.register`.\n * `Module.bind` is the same as `Module.register`\n * `Injector.get` is the same as `Injector.getInstance`\n * `Registration.to` is the same as `Registration.toType`\n\nBe aware that `Injector.register` and may become\ndepreciated in one of the next releases.\n\nPrefer the `bind`, `to and the `get` version over its equivalent.\n\n## Thanks\nThis package is based \"[Dice](https://pub.dartlang.org/packages/dice)\" - Thanks Lars Tackmann!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikemitterer%2Fdryice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikemitterer%2Fdryice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikemitterer%2Fdryice/lists"}