{"id":24055752,"url":"https://github.com/dawids222/di-lite","last_synced_at":"2025-06-26T08:03:41.303Z","repository":{"id":55377435,"uuid":"299090889","full_name":"dawids222/DI-Lite","owner":"dawids222","description":"Small and simple IoC container","archived":false,"fork":false,"pushed_at":"2022-10-26T16:36:20.000Z","size":114,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-10T02:40:01.097Z","etag":null,"topics":["container","csharp","csharp-library","dependency-injection","fast","ioc","ioc-container","library","lightweight","net"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dawids222.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}},"created_at":"2020-09-27T18:11:27.000Z","updated_at":"2022-12-08T08:03:34.000Z","dependencies_parsed_at":"2023-01-20T14:01:02.535Z","dependency_job_id":null,"html_url":"https://github.com/dawids222/DI-Lite","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dawids222/DI-Lite","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dawids222%2FDI-Lite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dawids222%2FDI-Lite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dawids222%2FDI-Lite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dawids222%2FDI-Lite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dawids222","download_url":"https://codeload.github.com/dawids222/DI-Lite/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dawids222%2FDI-Lite/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262026903,"owners_count":23246951,"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":["container","csharp","csharp-library","dependency-injection","fast","ioc","ioc-container","library","lightweight","net"],"created_at":"2025-01-09T04:30:49.770Z","updated_at":"2025-06-26T08:03:41.282Z","avatar_url":"https://github.com/dawids222.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# DI-Lite\n\nDI-Lite is a small size, high performance tool for storing and retrieving objects for dependency injection. Library is written in C# and has no external dependencies.\n\n# Table of contents\n- [Features](#Features)\n- [Examples](#Examples)\n- [Todos](#Todos)\n\n## Features\n\n  - Registering singletons\n  - Registering factories\n  - Registering scoped dependencies\n  - Removing registered dependencies\n  - Getting dependencies\n  - Scoping dependencies\n  - Auto creating objects based on their constructor\n  - Checking if all registered dependencies can be constructed\n  - Invoking delegates via Reflection\n\n## Examples\n\n ```CSharp\n// creating a DI container\n// container implements IDisposable interface in order to clean\n// after any resolved dependency that also implements IDisposable\n// that's why it is advised to instantiate it with 'using' keyword\n// or rememeber to call .Dispose() when it is no longed needed\nusing var Container = new Container();\n```\n\n ```CSharp\n// register singleton \n\n// object will be created once and then every Get call will return same object\nContainer.Single\u003cDependencyType\u003e(() =\u003e new DependencyImp());\n// dependency can have a tag to distinguish dependencies of the same type\nContainer.Single\u003cDependencyType\u003e(\"tag0\", () =\u003e new DependencyImp());\n\n// parameter of type 'IDependencyProvider' can be passed. This is instance on which we invoke 'Get' method.\nContainer.Single\u003cDependencyType\u003e(provider =\u003e new DependencyImp());\n// we can specify tag\nContainer.Single\u003cDependencyType\u003e(\"tag1\", provider =\u003e new DependencyImp());\n\n// already instantiated objects can be used\nContainer.Single\u003cDependencyType\u003e(dependencyInstance);\n\n// we can already use our container for creating new dependencies\nContainer.Single\u003cDependencyType\u003e(\"tag2\", () =\u003e new DependencyImp(Container.Get\u003cDependencyOfOurDependencyType\u003e()));\n\n// when no creation function is provided the object will be created using it's  constructor, but we have to provide its concrete class. Dependency class has to have exactly 1 constructor\nContainer.Single\u003cDependencyType, DependencyImp\u003e();\n// we can specify tag\nContainer.Single\u003cDependencyType, DependencyImp\u003e(\"tag3\");\n\n// if for some reason we don't want an abstraction then call can be simplified\nContainer.Single\u003cDependencyImp\u003e();\n// we can specify tag\nContainer.Single\u003cDependencyImp\u003e(\"tag4\");\n```\n\n ```CSharp\n// register factory\n\n// new object will be created with every Get call\nContainer.Factory\u003cDependencyType\u003e();\n// most overloads working with Single works with Factory with minor exceptions\n```\n\n ```CSharp\n// register scoped dependency\n\n// same object will be returned for a given scope\n// different scopes will return different objects\nContainer.Scoped\u003cDependencyType\u003e();\n// most overloads working with Single works with Scoped with minor exceptions\n```\n\n ```CSharp\n// register variants\n\n// every register method has Try and Force variant\nContainer.Factory(() =\u003e \"1\");\nContainer.Factory(() =\u003e \"2\"); // this will throw an exception\n/*******/\nContainer.Factory(() =\u003e \"1\");\nContainer.TryFactory(() =\u003e \"2\"); // this will not override the dependency\n/*******/\nContainer.Factory(() =\u003e \"1\"));\nContainer.ForceFactory(() =\u003e \"2\"); // this will override the dependency\n```\n\n ```CSharp\n// every depedency can be removed from a Container at any given time\n\n// remove all dependencies registed for a type\nContainer.Remove\u003cDependencyType\u003e();\n// remove all dependencies registed with a tag\nContainer.Remove(\"tag\");\n// remove dependency registed for a type with a tag (type and tag create KEY)\nContainer.Remove\u003cDependencyType\u003e(\"tag\");\n// remove all dependencies that match predicate\nContainer.Remove(dep =\u003e\n\t dep.Type != typeof(DependencyType) ||\n\t dep.Tag != null);\n// remove dependency with a given KEY\nvar key = Container.Dependencies.ElementAt(0).Key;\nContainer.Remove(key);\n// remove all dependencies by collection of KEYS\nvar keys = new DependencyKey[] {\n\tnew DependencyKey(typeof(DependencyType), null),\n\tnew DependencyKey(typeof(AnotherDependencyType), null),\n };\nContainer.Remove(keys);\n```\n\n ```CSharp\n// getting dependency object from container\n\n// regular containers are unable to Get scoped dependencies\nvar dependency = Container.Get\u003cDependencyType\u003e();\n// we can also get dependencies registered with tag\nvar dependency = Container.Get\u003cDependencyType\u003e(\"tag\");\n```\n\n ```CSharp\n// to Get scoped dependencies we first have to create a scope\n// scope implements IDisposable interface as container does\n// that's why it is advised to instantiate it with 'using' keyword\n// or rememeber to call .Dispose() when it is no longed needed\nusing var scope = Container.CreateScope();\n// scope is able to Get all kinds of dependencies\n// it is performed the same way as with Container\nvar dependency = scope.Get\u003cDependencyType\u003e();\n// or\nvar dependency = scope.Get\u003cDependencyType\u003e(\"tag\");\n```\n\n ```CSharp\n// to automatically inject dependency with tag specified we can add WithTag attribute to constructor's parameter\npublic class DependencyWithTag\n{\n    public DependencyWithTag([WithTag(\"MyTag\")] IMockDependency dependency) { }\n}\n// now we just have to registed required dependency\nContainer.Single\u003cIMockDependency, MockDependency\u003e(\"MyTag\");\nContainer.Single\u003cDependencyWithTag\u003e();\n// now registered IMockDependency with tag \"MyTag\" will be used to construct instance of DependencyWithTag\nContainer.Get\u003cDependencyWithTag\u003e();\n```\n\n ```CSharp\n// we can check if all registered dependencies are constructable in multiple ways\n\n// will simply check whether continer is constructable or not\nvar isConstructable = Container.IsConstructable;\n\n// will return an object telling if the container is constructable and what is missing\nvar constructabilityReport = Container.GetConstructabilityReport();\n\n// will throw if container is not constructable\nContainer.ThrowIfNotConstructable();\n```\n\n ```CSharp\n var container = new Container();\ncontainer.Single\u003cDependencyType, DependencyImp\u003e();\n// to automatically invoke a delegate we have to define providers \n// which will contain arguments for it\nvar providers = new IArgumentsProvider[]\n{\n\t// we can use our container to provider complex objects\n    new ContainerArgumentsProvider(container),\n\t// and a string dictionary to provide simple values\n    new DictionaryArgumentsProvider(\n        new Dictionary\u003cstring, string\u003e() {\n            { \"name\", \"David\" },\n            { \"age\", \"25\" },\n            { \"birthday\", \"1996-12-21 8:00:00\" }\n        }),\n};\n// aggreagted provider can be used to provide values from multiple sources\nvar provider = new AggregatedArgumentsProvider(providers);\n// here we define delegate we want to invoke\nvar del = (DependencyType dependency, string name, int age, DateTime birthday) =\u003e dependency.DoSomething(name, age, birthday);\n// then we can instantiate our invoker and invoke a delegate\nvar invoker = new DelegateInvoker(del, provider);\n// async\nvar result = await invoker.InvokeAsync();\n// or sync\nvar result = invoker.Invoke();\n```\n\n```CSharp\n// when using AggregatedArgumentsProvider we can use FromProvider attribute\n// to specify from which provider argument should be taken\n var container1 = new Container();\ncontainer1.Single\u003cIPet, Zerg\u003e();\ncontainer1.Single\u003cIPerson, Alien\u003e();\n\nvar container2 = new Container();\ncontainer2.Single\u003cIPet, Dog\u003e(\"Dog\");\ncontainer2.Single\u003cIPet, Zerg\u003e(\"Zerg\");\ncontainer2.Single\u003cIPerson, Human\u003e(\"Dawid\");\ncontainer2.Single\u003cIPerson, NinjeTurtle\u003e(\"Rafael\");\n\n var provider = new AggregatedArgumentsProvider(new IArgumentsProvider[]\n {\n \t\t// here we register providers with tags specified\n\t\tnew ContainerArgumentsProvider(container1, \"1\"),\n\t\tnew ContainerArgumentsProvider(container2, \"2\"),\n});\n// here we specifie that instance of IHuman has to be taken from provider with tag \"2\"\n// WithTag attribute can be used same as in standard DI scenario\nvar func = ([FromProvider(\"2\")][WithTag(\"Rafael\")] IPerson human) =\u003e human.Greet();\nvar invoker = new DelegateInvoker(func, provider);\n\ninvoker.Invoke();\n```\n\n### Todos\n\n - Write MORE Tests\n - Add method descriptions\n - Add example usecase classes\n - Add interface for 'Container'","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdawids222%2Fdi-lite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdawids222%2Fdi-lite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdawids222%2Fdi-lite/lists"}