{"id":23888357,"url":"https://github.com/devteam/ioccontainer","last_synced_at":"2025-04-10T04:53:32.963Z","repository":{"id":49521584,"uuid":"114877019","full_name":"DevTeam/IoCContainer","owner":"DevTeam","description":"Expressions based Inversion of Control container for .NET","archived":false,"fork":false,"pushed_at":"2023-01-14T13:06:32.000Z","size":20882,"stargazers_count":28,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T06:04:46.823Z","etag":null,"topics":["asp-net-core","blazor","dependency-injection","dotnet","dotnet-core","dotnet-standard","dotnetcore","entity-framework-core","expression-tree","framework","interception","inversion-of-control","ioc","ioc-container","ioc-framework"],"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/DevTeam.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":"2017-12-20T10:58:17.000Z","updated_at":"2024-11-15T22:53:04.000Z","dependencies_parsed_at":"2023-02-09T19:30:45.037Z","dependency_job_id":null,"html_url":"https://github.com/DevTeam/IoCContainer","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevTeam%2FIoCContainer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevTeam%2FIoCContainer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevTeam%2FIoCContainer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevTeam%2FIoCContainer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DevTeam","download_url":"https://codeload.github.com/DevTeam/IoCContainer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248161257,"owners_count":21057553,"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":["asp-net-core","blazor","dependency-injection","dotnet","dotnet-core","dotnet-standard","dotnetcore","entity-framework-core","expression-tree","framework","interception","inversion-of-control","ioc","ioc-container","ioc-framework"],"created_at":"2025-01-04T08:47:07.907Z","updated_at":"2025-04-10T04:53:32.929Z","avatar_url":"https://github.com/DevTeam.png","language":"C#","readme":"# Simple, powerful and fast Inversion of Control container for .NET\n\n[![NuGet](https://buildstats.info/nuget/IoC.Container)](https://www.nuget.org/packages/IoC.Container)\n[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)\n[\u003cimg src=\"http://teamcity.jetbrains.com/app/rest/builds/buildType:(id:OpenSourceProjects_DevTeam_IoCContainer_BuildAndTest)/statusIcon\"/\u003e](http://teamcity.jetbrains.com/viewType.html?buildTypeId=OpenSourceProjects_DevTeam_IoCContainer_BuildAndTest\u0026guest=1)\n\n#### Base concepts:\n\n- maximum performance\n  - based on compiled expressions\n  - free of boxing and unboxing\n  - avoid using delegates\n\n- thoughtful design\n  - code is fully independent of the IoC framework\n  - supports for BCL types out of the box\n  - ultra-fine tuning of generic types\n  - aspect-oriented DI\n  - predictable dependency graph\n  - _Func\u003c... ,T\u003e_ based factories passing a state\n\n## [Schrödinger's cat](Samples/ShroedingersCat) shows how it works [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://dotnetfiddle.net/YoDYA7)\n\n### The reality is that\n\n![Cat](https://github.com/DevTeam/IoCContainer/blob/master/Docs/Images/cat.jpg?raw=true)\n\n### Let's create an abstraction\n\n```csharp\ninterface IBox\u003cout T\u003e { T Content { get; } }\n\ninterface ICat { State State { get; } }\n\nenum State { Alive, Dead }\n```\n\n### Here is our implementation\n\n```csharp\nclass CardboardBox\u003cT\u003e : IBox\u003cT\u003e\n{\n    public CardboardBox(T content) =\u003e Content = content;\n\n    public T Content { get; }\n}\n\nclass ShroedingersCat : ICat\n{\n  // Represents the superposition of the states\n  private readonly Lazy\u003cState\u003e _superposition;\n\n  public ShroedingersCat(Lazy\u003cState\u003e superposition) =\u003e _superposition = superposition;\n\n  // Decoherence of the superposition at the time of observation via an irreversible process\n  public State State =\u003e _superposition.Value;\n\n  public override string ToString() =\u003e $\"{State} cat\";\n}\n```\n\n_It is important to note that our abstraction and our implementation do not know anything about any IoC containers at all._\n\n### Let's glue all together\n\nJust add the package reference to [IoC.Container](https://www.nuget.org/packages/IoC.Container). It ships entirely as NuGet packages.\n\n_Using NuGet packages allows you to optimize your application to include only the necessary dependencies._\n\n- Package Manager\n\n  ```\n  Install-Package IoC.Container\n  ```\n  \n- .NET CLI\n  \n  ```\n  dotnet add package IoC.Container\n  ```\n\nDeclare the required dependencies in a dedicated class *__Glue__*. It is possible to do this anywhere in your code, but putting this information in one place is often the better solution and helps keep your code more organized.\n\nBelow is the concept of mutable containers (_IMutableContainer_). Any binding is not irreversible. Thus the owner of a binding [can cancel this binding](#change-configuration-on-the-fly-) using the related binding token (_IToken_).\n\n```csharp\npublic class Glue : IConfiguration\n{\n  public IEnumerable\u003cIToken\u003e Apply(IMutableContainer container)\n  {\n    // Returns single token for 2 bindings\n    yield return container\n      // Represents a cardboard box with any content\n      .Bind\u003cIBox\u003cTT\u003e\u003e().To\u003cCardboardBox\u003cTT\u003e\u003e()\n      // Represents schrodinger's cat\n      .Bind\u003cICat\u003e().To\u003cShroedingersCat\u003e();\n\n    // Models a random subatomic event that may or may not occur\n    var indeterminacy = new Random();\n\n    // Represents a quantum superposition of 2 states: Alive or Dead\n    yield return container.Bind\u003cState\u003e().To(ctx =\u003e (State)indeterminacy.Next(2));\n  }\n}\n```\n\n_Defining generic type arguments using special marker types like [*__TT__*](#generic-autowiring-) in the sample above is one of the distinguishing features of this library. So there is an easy way to bind complex generic types with nested generic types and with any type constraints._\n\n### Time to open boxes!\n\n```csharp\n// Creates the Inversion of Control container\nusing var container = Container.Create().Using\u003cGlue\u003e();\n\n// Composition Root\n// Gets the cardboard box in the same way as the following expression:\n// var box = new CardboardBox\u003cICat\u003e(new ShroedingersCat(new Lazy\u003cState\u003e(() =\u003e (State)indeterminacy.Next(2))));\nvar box = container.Resolve\u003cIBox\u003cICat\u003e\u003e();\n\n// Checks the cat's state\nWriteLine(box.Content);\n```\n\nThis is a [*__Composition Root__*](https://blog.ploeh.dk/2011/07/28/CompositionRoot/) - a single place in an application where the composition of the object graphs for an application take place. Each instance is resolved by a strongly-typed block of statements like the operator new which is compiled on the fly from the corresponding expression tree with minimal impact on performance or memory consumption. For instance, the getting of a box looks like:\n\n```csharp\nvar indeterminacy = new Random();\nvar box = new CardboardBox\u003cICat\u003e(new ShroedingersCat(new Lazy\u003cState\u003e(() =\u003e (State)indeterminacy.Next(2))));\n```\n\nIt allows you to take full advantage of dependency injection everywhere and every time without any compromises in the same way as just a *__new__* keyword to create instances.\n\n## NuGet packages\n\n|     | binary packages | source code packages ¹ |\n| --- | --- | ---|\n| Container | [![NuGet](https://buildstats.info/nuget/IoC.Container)](https://www.nuget.org/packages/IoC.Container) | [![NuGet](https://buildstats.info/nuget/IoC.Container.Source)](https://www.nuget.org/packages/IoC.Container.Source) |\n| ASP.NET | [![NuGet](https://buildstats.info/nuget/IoC.AspNetCore)](https://www.nuget.org/packages/IoC.AspNetCore) | [![NuGet](https://buildstats.info/nuget/IoC.AspNetCore.Source)](https://www.nuget.org/packages/IoC.AspNetCore.Source) |\n| Interception | [![NuGet](https://buildstats.info/nuget/IoC.Interception)](https://www.nuget.org/packages/IoC.Interception) | [![NuGet](https://buildstats.info/nuget/IoC.Interception.Source)](https://www.nuget.org/packages/IoC.Interception.Source) |\n\n¹ _source code packages_ require C# 7.0 or higher\n\n## ASP.NET Core\n\n- Package Manager\n\n  ```\n  Install-Package IoC.AspNetCore\n  ```\n  \n- .NET CLI\n  \n  ```\n  dotnet add package IoC.AspNetCore\n  ```\n\nFor __ASP.NET Core 3+__ or __Blazor server__ create the _IoC container_ and use the service provider factory based on this container at [Main](Samples/WebApplication3/Program.cs)\n\n```csharp\npublic static void Main(string[] args)\n{\n  using var container = Container\n    // Creates an Inversion of Control container\n    .Create()\n    .Using\u003cClockConfiguration\u003e();\n\n  // Creates a host\n  using var host = Host\n    .CreateDefaultBuilder(args)\n    // Adds a service provider for the Inversion of Control container\n    .UseServiceProviderFactory(new ServiceProviderFactory(container))\n    .ConfigureWebHostDefaults(webBuilder =\u003e { webBuilder.UseStartup\u003cStartup\u003e(); })\n    .Build();\n\n  host.Run();\n}\n```\n\nFor more details please see [this sample](Samples/WebApplication3) or [this Blazor sample](Samples/BlazorServerApp).\n\nFor __Blazor WebAssembly__ create the _IoC container_ and use the service provider factory based on this container at [Main](Samples/BlazorWebAssemblyApp/Program.cs)\n\n```csharp\npublic static async Task Main(string[] args)\n{\n    using var container = Container\n      // Creates an Inversion of Control container\n      .Create()\n      .Using\u003cClockConfiguration\u003e();\n\n    var builder = WebAssemblyHostBuilder.CreateDefault(args);\n    builder.RootComponents.Add\u003cApp\u003e(\"app\");\n\n    // Adds a service provider for the Inversion of Control container\n    builder.ConfigureContainer(new ServiceProviderFactory(container));\n\n    await builder.Build().RunAsync();\n}\n```\n\nFor more details please see [this sample](Samples/BlazorWebAssemblyApp).\n\nFor __ASP.NET Core 2__ create the _IoC container_ with feature _AspNetCoreFeature_ and configure it at [Startup](Samples/WebApplication2/Startup.cs)\n\n```csharp\npublic IServiceProvider ConfigureServices(IServiceCollection services)\n{\n  services.AddMvc().AddControllersAsServices();\n\n  return Container\n    // Creates an Inversion of Control container\n    .Create()\n    // using ASP .NET Feature\n    .Using(new AspNetCoreFeature(services))\n    // using Glue\n    .Using\u003cGlue\u003e()\n    // Resolves IServiceProvider\n    .Resolve\u003cIServiceProvider\u003e();\n}\n```\n\nFor more details please see [this sample](Samples/WebApplication2).\n\n## Interception\n\n- Package Manager\n\n  ```\n  Install-Package IoC.Interception\n  ```\n  \n- .NET CLI\n  \n  ```\n  dotnet add package IoC.Interception\n  ```\n\nAdd _InterceptionFeature_ to intercept calls to _IService_ by your own _MyInterceptor_\n\n```csharp\nusing var container = Container\n  // Using the feature InterceptionFeature\n  .Using\u003cInterceptionFeature\u003e()\n  .Bind\u003cIService\u003e().To\u003cService\u003e()\n  // Intercepts any invocations to any instances resolved via IoC container\n  .Intercept(key =\u003e true, new MyInterceptor())\n\ncontainer.Resolve\u003cIService\u003e();\n\n```\n\nwhere _MyInterceptor_ looks like:\n\n```csharp\nclass MyInterceptor : IInterceptor\n{\n  // Intercepts invocations and appends some logic around\n  public void Intercept(IInvocation invocation)\n  {\n    ...\n    invocation.Proceed();\n    ...\n  }\n}\n```\n\nFor details please see [this sample](IoC.Tests/UsageScenarios/Interception.cs).\n\n## Why this one framework?\n\n### Graph of 27 transient instances\n\n![Transient](http://tcavs2015.cloudapp.net/guestAuth/app/rest/builds/buildType:DevTeam_IoCContainer_CreateReports,pinned:true,status:SUCCESS/artifacts/content/IoC.Benchmark.Transient-report.jpg)\n\n### Graph of 20 transient instances and 1 singleton instance\n\n![Singleton](http://tcavs2015.cloudapp.net/guestAuth/app/rest/builds/buildType:DevTeam_IoCContainer_CreateReports,pinned:true,status:SUCCESS/artifacts/content/IoC.Benchmark.Singleton-report.jpg)\n\n### Graph of 364 transient instances of unique type\n\n![Complex](http://tcavs2015.cloudapp.net/guestAuth/app/rest/builds/buildType:DevTeam_IoCContainer_CreateReports,pinned:true,status:SUCCESS/artifacts/content/IoC.Benchmark.Complex-report.jpg)\n\n### Graph of 22 transient instances, including 3 Func to create 4 instances each time\n\n![Func](http://tcavs2015.cloudapp.net/guestAuth/app/rest/builds/buildType:DevTeam_IoCContainer_CreateReports,pinned:true,status:SUCCESS/artifacts/content/IoC.Benchmark.Func-report.jpg)\n\n### Graph of 22 transient instances, including 3 arrays of 4 instances in each\n\n![Array](http://tcavs2015.cloudapp.net/guestAuth/app/rest/builds/buildType:DevTeam_IoCContainer_CreateReports,pinned:true,status:SUCCESS/artifacts/content/IoC.Benchmark.Array-report.jpg)\n\n### Graph of 22 transient instances, including 3 enumerable of 4 instances in each\n\n![Enum](http://tcavs2015.cloudapp.net/guestAuth/app/rest/builds/buildType:DevTeam_IoCContainer_CreateReports,pinned:true,status:SUCCESS/artifacts/content/IoC.Benchmark.Enum-report.jpg)\n\n- __new__ - _Method_ when the graph of objects was constructed by operators _new_ only\n- __Mean__ - arithmetic mean of the root instances resolved per nanosecond\n- __Error__ - half of 99.9% confidence interval\n- __StdDev__ - standard deviation of all measurements\n- __Median__ - value separating the higher half of all measurements (50th percentile)\n- __1 ns__ - 1 Nanosecond (0.000000001 sec)\n\n_[BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet) was used to measure and analyze these results._\n\n### Supported Platforms\n\n- .NET 4.0+\n- [.NET Core](https://docs.microsoft.com/en-us/dotnet/core/) 1.0+\n- [.NET Standard](https://docs.microsoft.com/en-us/dotnet/standard/net-standard) 1.0+\n- [UWP](https://docs.microsoft.com/en-us/windows/uwp/index) 10+\n\n### Easy Integration\n\n- [ASP.NET Core](#aspnet-core)\n- [Xamarin](https://github.com/DevTeam/IoCContainer/blob/master/Samples/XamarinXaml)\n- [Windows Presentation Foundation](https://github.com/DevTeam/IoCContainer/blob/master/Samples/WpfApp)\n- [.NET core Windows Presentation Foundation](https://github.com/DevTeam/IoCContainer/blob/master/Samples/WpfAppNetCore) \n- [Universal Windows Platform](https://github.com/DevTeam/IoCContainer/blob/master/Samples/UwpApp)\n- [Windows Communication Foundation](https://github.com/DevTeam/IoCContainer/blob/master/Samples/WcfServiceLibrary)\n- [Entity Framework](https://github.com/DevTeam/IoCContainer/tree/master/Samples/EntityFrameworkCore)\n\n\n## Usage Scenarios\n\n- Basics\n  - [Composition Root](#composition-root-)\n  - [Autowiring](#autowiring-)\n  - [Bindings](#bindings-)\n  - [Constants](#constants-)\n  - [Factories](#factories-)\n  - [Generics](#generics-)\n  - [Tags](#tags-)\n  - [Wrapper](#wrapper-)\n  - [Aspect-oriented DI](#aspect-oriented-di-)\n  - [Configurations](#configurations-)\n  - [Resolve Unbound](#resolve-unbound-)\n  - [Several contracts](#several-contracts-)\n  - [Autowiring with initialization](#autowiring-with-initialization-)\n  - [Child container](#child-container-)\n  - [Expression binding](#expression-binding-)\n  - [Method injection](#method-injection-)\n  - [Setter or field injection](#setter-or-field-injection-)\n  - [Dependency tag](#dependency-tag-)\n  - [Manual wiring](#manual-wiring-)\n  - [Func dependency](#func-dependency-)\n  - [Value types](#value-types-)\n  - [Generic autowiring](#generic-autowiring-)\n  - [Injection of default parameters](#injection-of-default-parameters-)\n  - [Optional injection](#optional-injection-)\n  - [Resolve an instance using arguments](#resolve-an-instance-using-arguments-)\n  - [Auto Disposing](#auto-disposing-)\n- Lifetimes\n  - [Container Singleton lifetime](#container-singleton-lifetime-)\n  - [Disposing lifetime](#disposing-lifetime-)\n  - [Scope Root lifetime](#scope-root-lifetime-)\n  - [Singleton lifetime](#singleton-lifetime-)\n  - [Custom lifetime: thread Singleton](#custom-lifetime:-thread-singleton-)\n  - [Replacement of Lifetime](#replacement-of-lifetime-)\n- BCL types\n  - [Arrays](#arrays-)\n  - [Collections](#collections-)\n  - [Enumerables](#enumerables-)\n  - [Funcs](#funcs-)\n  - [Lazy](#lazy-)\n  - [Nullable value type](#nullable-value-type-)\n  - [Observables](#observables-)\n  - [Sets](#sets-)\n  - [ThreadLocal](#threadlocal-)\n  - [Tuples](#tuples-)\n  - [Value Tuples](#value-tuples-)\n  - [Func with arguments](#func-with-arguments-)\n- Async\n  - [ValueTask](#valuetask-)\n  - [Async Enumerables](#async-enumerables-)\n  - [Asynchronous construction](#asynchronous-construction-)\n  - [Cancellation of asynchronous construction](#cancellation-of-asynchronous-construction-)\n  - [Override the default task scheduler](#override-the-default-task-scheduler-)\n- Advanced\n  - [Change configuration on-the-fly](#change-configuration-on-the-fly-)\n  - [Resolve Unbound for abstractions](#resolve-unbound-for-abstractions-)\n  - [Constructor choice](#constructor-choice-)\n  - [Container injection](#container-injection-)\n  - [Check a binding](#check-a-binding-)\n  - [Check for possible resolving](#check-for-possible-resolving-)\n  - [Tracing](#tracing-)\n  - [Custom autowiring strategy](#custom-autowiring-strategy-)\n  - [Custom builder](#custom-builder-)\n  - [Custom child container](#custom-child-container-)\n  - [Interception](#interception-)\n- Samples\n  - [Cyclic dependency](#cyclic-dependency-)\n  - [Plugins](#plugins-)\n  - [Generator sample](#generator-sample-)\n  - [Wrapper sample](#wrapper-sample-)\n  - [Instant Messenger sample](#instant-messenger-sample-)\n\n### Composition Root [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/CompositionRoot.cs)\n\n\n\n``` CSharp\npublic void Run()\n{\n    // Host runs a program\n    Program.TestMain();\n}\n\nclass Program\n{\n    // The application's entry point\n    public static void TestMain()\n    {\n        using var container =\n            Container.Create()\n            .Using\u003cConfiguration\u003e();\n\n        // The Composition Root is a single location for objects construction\n        // it should be as close as possible to the application's entry point\n        var root = container.Resolve\u003cProgram\u003e();\n\n        // Runs a logic\n        root.Run();\n    }\n\n    // Injects dependencies via a constructor\n    internal Program(IService service)\n    {\n         // Saves dependencies as internal fields\n    }\n\n    private void Run()\n    {\n        // Implements a logic using dependencies\n    }\n}\n\n// Represents the IoC container configuration\nclass Configuration: IConfiguration\n{\n    public IEnumerable\u003cIToken\u003e Apply(IMutableContainer container)\n    {\n        yield return container\n            .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n            .Bind\u003cIService\u003e().To\u003cService\u003e();\n    }\n}\n```\n\n\n\n### Autowiring [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Autowiring.cs)\n\nAutowring is the most natural way to use containers. In the first step, we should create a container. At the second step, we bind interfaces to their implementations. After that, the container is ready to resolve dependencies.\n\n``` CSharp\n// Create the container and configure it, using full autowiring\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    .Bind\u003cIService\u003e().To\u003cService\u003e()\n    .Container;\n\n// Resolve an instance of interface `IService`\nvar instance = container.Resolve\u003cIService\u003e();\n```\n\n\n\n### Bindings [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Bindings.cs)\n\nIt is possible to bind any number of types.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind using few types\n    .Bind\u003cIService\u003e().Bind\u003cIAnotherService\u003e().Tag(\"abc\").To\u003cService\u003e()\n    .Container;\n\n// Resolve instances using different types\nvar instance1 = container.Resolve\u003cIService\u003e(\"abc\".AsTag());\nvar instance2 = container.Resolve\u003cIAnotherService\u003e(\"abc\".AsTag());\n```\n\n\n\n### Constants [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Constants.cs)\n\nIt's obvious here.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cint\u003e().To(ctx =\u003e 10)\n    .Container;\n// Resolve an integer\nvar val = container.Resolve\u003cint\u003e();\n// Check the value\nval.ShouldBe(10);\n```\n\n\n\n### Factories [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Factories.cs)\n\nUse _Func\u003c..., T\u003e_ with arguments as a factory passing a state.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    .Bind\u003cINamedService\u003e().To\u003cNamedService\u003e()\n    .Container;\n\n// Resolve a factory\nvar factory = container.Resolve\u003cFunc\u003cstring, INamedService\u003e\u003e();\n\n// Run factory passing the string \"beta\" as argument\nvar instance = factory(\"alpha\");\n\n// Check that argument \"beta\" was used during constructing an instance\ninstance.Name.ShouldBe(\"alpha\");\n```\n\nIt is better to pass a state using a special type (but not via any base type like in the sample above) because in this case, it will be possible to create a complex object graph with a special state for every object within this graph.\n\n### Generics [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Generics.cs)\n\nAutowring of generic types via binding of open generic types or generic type markers are working the same way.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind open generic interface to open generic implementation\n    .Bind(typeof(IService\u003c\u003e)).To(typeof(Service\u003c\u003e))\n    // Or (it is working the same) just bind generic interface to generic implementation, using marker classes TT, TT1, TT2 and so on\n    .Bind\u003cIService\u003cTT\u003e\u003e().Tag(\"just generic\").To\u003cService\u003cTT\u003e\u003e()\n    .Container;\n\n// Resolve a generic instance using \"open generic\" binding\nvar instance1 = container.Resolve\u003cIService\u003cint\u003e\u003e();\n\n// Resolve a generic instance using \"just generic\" binding\nvar instance2 = container.Resolve\u003cIService\u003cstring\u003e\u003e(\"just generic\".AsTag());\n```\n\n\n\n### Wrapper [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/SimpleWrapper.cs)\n\n\n\n``` CSharp\npublic void Run()\n{\n    // Create and configure a parent container\n    using var parentContainer = Container\n        .Create()\n        // Binds a service to wrap\n        .Bind\u003cIService\u003e().To\u003cService\u003e()\n        .Container;\n\n    // Create and configure a child container\n    using var childContainer = parentContainer\n        .Create()\n        // Binds a wrapper, injecting the base IService from the parent container via constructor\n        .Bind\u003cIService\u003e().To\u003cWrapperForService\u003e()\n        .Container;\n\n    var service = childContainer.Resolve\u003cIService\u003e();\n\n    service.Value.ShouldBe(\"Wrapper abc\");\n}\n\npublic interface IService\n{\n    string Value { get; }\n}\n\npublic class Service: IService\n{\n    public string Value =\u003e \"abc\";\n}\n\npublic class WrapperForService : IService\n{\n    private readonly IService _wrapping;\n\n    public WrapperForService(IService wrapping) =\u003e _wrapping = wrapping;\n\n    public string Value =\u003e $\"Wrapper {_wrapping.Value}\";\n}\n```\n\n\n\n### Tags [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Tags.cs)\n\nTags are useful while binding to several implementations of the same abstract types.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind using several tags\n    .Bind\u003cIService\u003e().Tag(10).Tag().Tag(\"abc\").To\u003cService\u003e()\n    .Container;\n\n// Resolve instances using tags\nvar instance1 = container.Resolve\u003cIService\u003e(\"abc\".AsTag());\nvar instance2 = container.Resolve\u003cIService\u003e(10.AsTag());\n\n// Resolve the instance using the empty tag\nvar instance3 = container.Resolve\u003cIService\u003e();\n```\n\n\n\n### Aspect-oriented DI [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/AspectOriented.cs)\n\nThis framework has no special predefined attributes to support aspect-oriented auto wiring because a non-infrastructure code should not have references to this framework. But this code may contain these attributes by itself. And it is quite easy to use these attributes for aspect-oriented auto wiring, see the sample below.\n\n``` CSharp\npublic void Run()\n{\n    var console = new Mock\u003cIConsole\u003e();\n\n    // Creates an aspect - oriented auto wiring strategy specifying\n    // which attributes should be used and which properties should be used to configure DI\n    var autowiringStrategy = AutowiringStrategies.AspectOriented()\n        .Type\u003cTypeAttribute\u003e(attribute =\u003e attribute.Type)\n        .Order\u003cOrderAttribute\u003e(attribute =\u003e attribute.Order)\n        .Tag\u003cTagAttribute\u003e(attribute =\u003e attribute.Tag);\n\n    using var container = Container\n        .Create()\n        // Configure the container to use DI aspects\n        .Bind\u003cIAutowiringStrategy\u003e().To(ctx =\u003e autowiringStrategy)\n        .Bind\u003cIConsole\u003e().Tag(\"MyConsole\").To(ctx =\u003e console.Object)\n        .Bind\u003cstring\u003e().Tag(\"Prefix\").To(ctx =\u003e \"info\")\n        .Bind\u003cILogger\u003e().To\u003cLogger\u003e()\n        .Container;\n\n    // Create a logger\n    var logger = container.Resolve\u003cILogger\u003e();\n\n    // Log the message\n    logger.Log(\"Hello\");\n\n    // Check the output has the appropriate format\n    console.Verify(i =\u003e i.WriteLine(It.IsRegex(\".+ - info: Hello\")));\n}\n\n// Represents the dependency aspect attribute to specify a type for injection.\n[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]\npublic class TypeAttribute : Attribute\n{\n    // A type, which will be used during an injection\n    public readonly Type Type;\n\n    public TypeAttribute(Type type) =\u003e Type = type;\n}\n\n// Represents the dependency aspect attribute to specify a tag for injection.\n[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]\npublic class TagAttribute : Attribute\n{\n    // A tag, which will be used during an injection\n    public readonly object Tag;\n\n    public TagAttribute(object tag) =\u003e Tag = tag;\n}\n\n// Represents the dependency aspect attribute to specify an order for injection.\n[AttributeUsage(AttributeTargets.Method)]\npublic class OrderAttribute : Attribute\n{\n    // An order to be used to invoke a method\n    public readonly int Order;\n\n    public OrderAttribute(int order) =\u003e Order = order;\n}\n\npublic interface IConsole { void WriteLine(string text); }\n\npublic interface IClock { DateTimeOffset Now { get; } }\n\npublic interface ILogger { void Log(string message); }\n\npublic class Logger : ILogger\n{\n    private readonly IConsole _console;\n    private IClock _clock;\n\n    // Constructor injection using the tag \"MyConsole\"\n    public Logger([Tag(\"MyConsole\")] IConsole console) =\u003e _console = console;\n\n    // Method injection after constructor using specified type _Clock_\n    [Order(1)] public void Initialize([Type(typeof(Clock))] IClock clock) =\u003e _clock = clock;\n\n    // Setter injection after the method injection above using the tag \"Prefix\"\n    public string Prefix { get; [Tag(\"Prefix\"), Order(2)] set; }\n\n    // Adds current time and prefix before a message and writes it to console\n    public void Log(string message) =\u003e _console?.WriteLine($\"{_clock.Now} - {Prefix}: {message}\");\n}\n\npublic class Clock : IClock\n{\n    // \"clockName\" dependency is not resolved here but has default value\n    public Clock([Type(typeof(string)), Tag(\"ClockName\")] string clockName = \"SPb\") { }\n\n    public DateTimeOffset Now =\u003e DateTimeOffset.Now;\n}\n```\n\nYou can also specify your own aspect-oriented auto wiring by implementing the interface [_IAutowiringStrategy_](IoCContainer/blob/master/IoC/IAutowiringStrategy.cs).\n\n### Configurations [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Configurations.cs)\n\nConfigurations are used to dedicate a logic responsible for configuring containers.\n\n``` CSharp\npublic void Run()\n{\n    using var container = Container\n        .Create()\n        .Using\u003cGlue\u003e();\n\n    var instance = container.Resolve\u003cIService\u003e();\n}\n\npublic class Glue : IConfiguration\n{\n    public IEnumerable\u003cIToken\u003e Apply(IMutableContainer container)\n    {\n        yield return container\n            .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n            .Bind\u003cIService\u003e().To\u003cService\u003e();\n    }\n}\n```\n\n\n\n### Resolve Unbound [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ResolveUnbound.cs)\n\nBy default, all instances of non-abstract or value types are ready to resolve and inject as dependencies.\n\n``` CSharp\npublic void Run()\n{\n    using var container = Container\n        .Create()\n        .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n        .Container;\n\n    // Resolve an instance of unregistered type\n    var instance = container.Resolve\u003cService\u003cint\u003e\u003e(99);\n    instance.OtherService.Value.ShouldBe(99);\n    instance.OtherService.Count.ShouldBe(10);\n}\n\nclass Service\u003cT\u003e\n{\n    public Service(OtherService\u003cT\u003e otherService, IDependency dependency)\n    {\n        OtherService = otherService;\n    }\n\n    public OtherService\u003cT\u003e OtherService { get; }\n}\n\nclass OtherService\u003cT\u003e\n{\n    public OtherService(T value, int count = 10)\n    {\n        Value = value;\n        Count = count;\n    }\n\n    public T Value { get; }\n\n    public long Count { get; }\n}\n```\n\nIn the case when context arguments contain instances of suitable types and a container has no appropriate bindings context arguments will be used for resolving and injections.\n\n### Several contracts [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/SeveralContracts.cs)\n\nIt is possible to bind several types to a single implementation.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    .Bind\u003cService, IService, IAnotherService\u003e().To\u003cService\u003e()\n    .Container;\n\n// Resolve instances\nvar instance1 = container.Resolve\u003cIService\u003e();\nvar instance2 = container.Resolve\u003cIAnotherService\u003e();\n```\n\n\n\n### Autowiring with initialization [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/AutoWiringWithInitialization.cs)\n\nSometimes instances required some actions before you give them to use - some methods of initialization or fields which should be defined. You can solve these things easily.\n\n``` CSharp\n// Create a container and configure it using full autowiring\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    .Bind\u003cINamedService\u003e().To\u003cInitializingNamedService\u003e(\n        // Configure the container to invoke method \"Initialize\" for every created instance of this type\n        ctx =\u003e ctx.It.Initialize(\"Initialized!\", ctx.Container.Resolve\u003cIDependency\u003e()))\n    .Container;\n\n// Resolve an instance of interface `IService`\nvar instance = container.Resolve\u003cINamedService\u003e();\n\n// Check the instance\ninstance.ShouldBeOfType\u003cInitializingNamedService\u003e();\n\n// Check that the initialization has took place\ninstance.Name.ShouldBe(\"Initialized!\");\n```\n\n:warning: It is not recommended because it is a cause of hidden dependencies.\n\n### Child container [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ChildContainer.cs)\n\nChild containers allow to override or just to add bindings without any influence on parent containers. This is useful when few components have their own child containers with additional bindings based on a common parent container.\n\n``` CSharp\nusing var parentContainer = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind IService to Service\n    .Bind\u003cIService\u003e().To\u003cService\u003e()\n    .Container;\n\nusing var childContainer = parentContainer\n    .Create()\n    // Override binding of IService to Service\u003cint\u003e\n    .Bind\u003cIService\u003e().To\u003cService\u003cint\u003e\u003e()\n    .Container;\n\nvar instance1 = parentContainer.Resolve\u003cIService\u003e();\nvar instance2 = childContainer.Resolve\u003cIService\u003e();\n\nchildContainer.Parent.ShouldBe(parentContainer);\ninstance1.ShouldBeOfType\u003cService\u003e();\ninstance2.ShouldBeOfType\u003cService\u003cint\u003e\u003e();\n```\n\n\n\n### Expression binding [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ExpressionBinding.cs)\n\nA specific type is bound as a part of an expression tree. This dependency will be introduced as is, without any additional overhead like _lambda call_ or _type cast_.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIService\u003e().To(ctx =\u003e new Service(new Dependency()))\n    .Container;\n\n// Resolve an instance\nvar instance = container.Resolve\u003cIService\u003e();\n```\n\n\n\n### Method injection [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/MethodInjection.cs)\n\n:warning: Please use the constructor injection instead. The method injection is not recommended because it is a cause of hidden dependencies.\n\n``` CSharp\n// Create and configure a container using full autowiring\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind 'INamedService' to the instance creation and initialization, actually represented as an expression tree\n    .Bind\u003cINamedService\u003e().To\u003cInitializingNamedService\u003e(\n        // Select the constructor and inject a dependency into it\n        ctx =\u003e new InitializingNamedService(ctx.Container.Inject\u003cIDependency\u003e()),\n        // Configure the initializing method to invoke after the instance creation and inject the dependencies\n        // The first one is the value from context arguments at index 0\n        // The second one - is just dependency injection of type IDependency\n        ctx =\u003e ctx.It.Initialize((string) ctx.Args[0], ctx.Container.Inject\u003cIDependency\u003e()))\n    .Container;\n\n// Resolve the instance using the argument \"alpha\"\nvar instance = container.Resolve\u003cINamedService\u003e(\"alpha\");\n\n// Check the instance type\ninstance.ShouldBeOfType\u003cInitializingNamedService\u003e();\n\n// Check the injected dependency\ninstance.Name.ShouldBe(\"alpha\");\n\n// Resolve a function to create an instance\nvar func = container.Resolve\u003cFunc\u003cstring, INamedService\u003e\u003e();\n\n// Create an instance with the argument \"beta\"\nvar otherInstance = func(\"beta\");\n\n// Check the injected dependency\notherInstance.Name.ShouldBe(\"beta\");\n```\n\nIt is possible to use DI aspects (Attributes) to use full autowring instead.\n\n### Setter or field injection [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/SetterInjection.cs)\n\n:warning: Please try using the constructor injection instead. The setter/field injection is not recommended because of it is a cause of hidden dependencies.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind 'INamedService' to the instance creation and initialization, actually represented as an expression tree\n    .Bind\u003cINamedService\u003e().To\u003cInitializingNamedService\u003e(\n        // Select a constructor and inject the dependency\n        ctx =\u003e new InitializingNamedService(ctx.Container.Inject\u003cIDependency\u003e()),\n        // Select a setter/field to inject after the instance creation and inject the value from arguments at index 0\n        ctx =\u003e ctx.Container.Assign(ctx.It.Name, (string)ctx.Args[0]))\n    .Container;\n\n// Resolve the instance using the argument \"alpha\"\nvar instance = container.Resolve\u003cINamedService\u003e(\"alpha\");\n\n// Check the instance type\ninstance.ShouldBeOfType\u003cInitializingNamedService\u003e();\n\n// Check the injected dependency\ninstance.Name.ShouldBe(\"alpha\");\n\n// Resolve a function to create an instance\nvar func = container.Resolve\u003cFunc\u003cstring, INamedService\u003e\u003e();\n\n// Create an instance with the argument \"beta\"\nvar otherInstance = func(\"beta\");\n\n// Check the injected dependency\notherInstance.Name.ShouldBe(\"beta\");\n```\n\nIt is possible to use DI aspects (Attributes) to use full autowring instead.\n\n### Dependency tag [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/DependencyTag.cs)\n\nUse a _tag_ to bind few dependencies for the same types.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().Tag(\"MyDep\").To\u003cDependency\u003e()\n    // Configure autowiring and inject dependency tagged by \"MyDep\"\n    .Bind\u003cIService\u003e().To\u003cService\u003e(ctx =\u003e new Service(ctx.Container.Inject\u003cIDependency\u003e(\"MyDep\")))\n    .Container;\n\n// Resolve an instance\nvar instance = container.Resolve\u003cIService\u003e();\n```\n\n\n\n### Manual wiring [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ManualWiring.cs)\n\nIn the case when the full control of creating an instance is required it is possible to do it in a simple way without any performance impact.\n\n``` CSharp\n// Create and configure a container using manual wiring\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind 'INamedService' to the instance creation and initialization, actually represented as an expression tree\n    .Bind\u003cINamedService\u003e().To\u003cInitializingNamedService\u003e(\n        // Select the constructor and inject a dependency into it\n        ctx =\u003e new InitializingNamedService(ctx.Container.Inject\u003cIDependency\u003e()),\n        // Configure the initializing method to invoke for every created instance with all appropriate dependencies\n        // We used _Resolve_ instead _Inject_ just for example\n        ctx =\u003e ctx.It.Initialize(\"some name\", ctx.Container.Resolve\u003cIDependency\u003e()))\n    .Container;\n\n// Resolve an instance\nvar instance = container.Resolve\u003cINamedService\u003e();\n\n// Check the instance\ninstance.ShouldBeOfType\u003cInitializingNamedService\u003e();\n\n// Check the injected dependency\ninstance.Name.ShouldBe(\"some name\");\n```\n\nIt's important to note that injection is possible in several ways in the sample above. **The first one** is an expressions like `ctx.Container.Inject\u003cIDependency\u003e()`. It uses the injection context `ctx` to access the current (or other parents) container and method `Inject` to inject a dependency. But actually, this method has no implementation. It just a marker and every such method will be replaced by an expression that creates dependency in place without any additional invocations. **Another way** is to use an expression like `ctx.Resolve\u003cIDependency\u003e()`. It will access a container each time to resolve a dependency. Each time, it will look for the necessary binding in the container and call the method to create an instance of the dependency type. **We recommend: wherever possible, use the first approach like `ctx.Container.Inject\u003cIDependency\u003e()`.**\n\n### Func dependency [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/FuncDependency.cs)\n\nNo comments. Everything is very simple!\n\n``` CSharp\nFunc\u003cIService\u003e func = () =\u003e new Service(new Dependency());\n\nusing var container = Container\n    .Create()\n    .Bind\u003cIService\u003e().To(ctx =\u003e func())\n    .Container;\n\nvar instance = container.Resolve\u003cIService\u003e();\n```\n\n\n\n### Value types [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Structs.cs)\n\nValue types are fully supported avoiding any boxing/unboxing or cast operations, so the performance does not suffer!\n\n``` CSharp\npublic void Run()\n{\n    using var container = Container\n        .Create()\n        .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n        // Register the tracing builder\n        .Bind\u003cTracingBuilder, IBuilder\u003e().As(Singleton).To\u003cTracingBuilder\u003e()\n        // Register a struct\n        .Bind\u003cMyStruct\u003e().To\u003cMyStruct\u003e()\n        .Container;\n\n    // Resolve an instance\n    var instance = container.Resolve\u003cMyStruct\u003e();\n\n    // Check the expression which was used to create an instances of MyStruct\n    var expressions = container.Resolve\u003cTracingBuilder\u003e().Expressions;\n    var structExpression = expressions[new Key(typeof(MyStruct))].ToString();\n    // The actual code is \"new MyStruct(new Dependency())\"!\n    structExpression.ShouldBe(\"new MyStruct(new Dependency())\");\n    // Obvious there are no any superfluous operations like a `boxing`, `unboxing` or `cast`,\n    // just only what is really necessary to create an instance\n}\n\npublic struct MyStruct\n{\n    public MyStruct(IDependency dependency) { }\n}\n\n// This builder saves expressions that used to create resolvers\npublic class TracingBuilder : IBuilder\n{\n    public readonly IDictionary\u003cKey, Expression\u003e Expressions = new Dictionary\u003cKey, Expression\u003e();\n\n    public Expression Build(IBuildContext context, Expression expression)\n    {\n        Expressions[context.Key] = expression;\n        return expression;\n    }\n}\n```\n\n\n\n### Injection of default parameters [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/DefaultParamsInjection.cs)\n\n\n\n``` CSharp\npublic void Run()\n{\n    using var container = Container.Create()\n        .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n        .Bind\u003cIService\u003e().To\u003cSomeService\u003e()\n        .Container;\n\n    // Resolve an instance\n    var instance = container.Resolve\u003cIService\u003e();\n\n    // Check the optional dependency\n    instance.State.ShouldBe(\"empty\");\n}\n\npublic class SomeService: IService\n{\n    // \"state\" dependency is not resolved here but it has the default value \"empty\"\n    public SomeService(IDependency dependency, string state = \"empty\")\n    {\n        Dependency = dependency;\n        State = state;\n    }\n\n    public IDependency Dependency { get; }\n\n    public string State { get; }\n}\n```\n\n\n\n### Generic autowiring [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/GenericAutowiring.cs)\n\nAutowiring of generic types as simple as autowiring of other simple types. Just use a generic parameters markers like _TT_, _TT1_, _TT2_ and etc. or TTI, TTI1, TTI2 ... for interfaces or TTS, TTS1, TTS2 ... for value types or other special markers like TTDisposable, TTDisposable1 and etc. TTList\u003c\u003e, TTDictionary\u003c\u003e ... or create your own generic parameters markers or bind open generic types.\n\n``` CSharp\npublic void Run()\n{\n    // Create and configure the container using autowiring\n    using var container = Container\n        .Create()\n        .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n        // Bind using the predefined generic parameters marker TT (or TT1, TT2, TT3 ...)\n        .Bind\u003cIService\u003cTT\u003e\u003e().To\u003cService\u003cTT\u003e\u003e()\n        // Bind using the predefined generic parameters marker TTList (or TTList1, TTList2 ...)\n        // For other cases there are TTComparable, TTComparable\u003cin T\u003e, TTEquatable\u003cT\u003e, TTEnumerable\u003cout T\u003e, TTDictionary\u003cTKey, TValue\u003e and etc.\n        .Bind\u003cIListService\u003cTTList\u003cint\u003e\u003e\u003e().To\u003cListService\u003cTTList\u003cint\u003e\u003e\u003e()\n        // Bind using the custom generic parameters marker TCustom\n        .Bind\u003cIService\u003cTTMy\u003e\u003e().Tag(\"custom marker\").To\u003cService\u003cTTMy\u003e\u003e()\n        // Bind using the open generic type\n        .Bind(typeof(IService\u003c\u003e)).Tag(\"open type\").To(typeof(Service\u003c\u003e))\n        .Container;\n\n    // Resolve a generic instance\n    var listService = container.Resolve\u003cIListService\u003cIList\u003cint\u003e\u003e\u003e();\n    var instances = container.Resolve\u003cICollection\u003cIService\u003cint\u003e\u003e\u003e();\n\n    instances.Count.ShouldBe(3);\n    // Check the instance's type\n    foreach (var instance in instances)\n    {\n        instance.ShouldBeOfType\u003cService\u003cint\u003e\u003e();\n    }\n\n    listService.ShouldBeOfType\u003cListService\u003cIList\u003cint\u003e\u003e\u003e();\n}\n\n// Custom generic type marker using predefined attribute `GenericTypeArgument`\n[GenericTypeArgument]\nclass TTMy { }\n```\n\n\n\n### Optional injection [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/OptionalInjection.cs)\n\n\n\n``` CSharp\npublic void Run()\n{\n    using var container = Container.Create()\n        .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n        .Bind\u003cIService\u003e().To\u003cSomeService\u003e(ctx =\u003e \n            new SomeService(\n                ctx.Container.Inject\u003cIDependency\u003e(),\n                // Injects default(string) if the dependency cannot be resolved\n                ctx.Container.TryInject\u003cstring\u003e(),\n                // Injects default(int) if the dependency cannot be resolved\n                ctx.Container.TryInject\u003cint\u003e(),\n                // Injects int? if the dependency cannot be resolved\n                ctx.Container.TryInjectValue\u003cint\u003e()))\n        .Container;\n\n    // Resolve an instance\n    var instance = container.Resolve\u003cIService\u003e();\n\n    // Check optional dependencies\n    instance.State.ShouldBe(\"empty,True,False\");\n}\n\npublic class SomeService: IService\n{\n    public SomeService(IDependency dependency, string state, int? val1, int? val2)\n    {\n        Dependency = dependency;\n        State = state ?? $\"empty,{val1.HasValue},{val2.HasValue}\";\n    }\n\n    public IDependency Dependency { get; }\n\n    public string State { get; }\n}\n```\n\n\n\n### Resolve an instance using arguments [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ResolveWithArgs.cs)\n\n\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind 'INamedService' to the instance creation and initialization, actually represented as an expression tree\n    .Bind\u003cINamedService\u003e().To\u003cNamedService\u003e(\n        // Select the constructor and inject the value from arguments at index 0\n        ctx =\u003e new NamedService(ctx.Container.Inject\u003cIDependency\u003e(), (string) ctx.Args[0]))\n    .Container;\n\n// Resolve the instance using the argument \"alpha\"\nvar instance = container.Resolve\u003cINamedService\u003e(\"alpha\");\n\n// Check the instance type\ninstance.ShouldBeOfType\u003cNamedService\u003e();\n\n// Check the injected dependency\ninstance.Name.ShouldBe(\"alpha\");\n\n// Resolve a function to create an instance\nvar func = container.Resolve\u003cFunc\u003cstring, INamedService\u003e\u003e();\n\n// Create an instance with the argument \"beta\"\nvar otherInstance = func(\"beta\");\n\n// Check the injected dependency\notherInstance.Name.ShouldBe(\"beta\");\n```\n\n\n\n### Auto Disposing [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/AutoDisposing.cs)\n\nA [singleton](https://en.wikipedia.org/wiki/Singleton_pattern) instance it's a very special instance. If it implements the _IDisposable_ (or IAsyncDisposable) interface the _Sigleton_ lifetime takes care of disposing of this instance after disposing of the owning container (where this type was registered) or if after the binding cancellation.\n\n``` CSharp\nvar disposableService = new Mock\u003cIDisposableService\u003e();\n\nusing (\n    var container = Container\n    .Create()\n    .Bind\u003cIService\u003e().As(Lifetime.Singleton).To\u003cIDisposableService\u003e(ctx =\u003e disposableService.Object)\n    .Container)\n{\n    var disposableInstance = container.Resolve\u003cIService\u003e();\n}\n\n// Check the singleton was disposed after the container was disposed\ndisposableService.Verify(i =\u003e i.Dispose(), Times.Once);\ndisposableService.Verify(i =\u003e i.DisposeAsync(), Times.Once);\n```\n\n\n\n### Container Singleton lifetime [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ContainerLifetime.cs)\n\nEach container may have its own [singleton](https://en.wikipedia.org/wiki/Singleton_pattern) instance for specific binding.\n\n``` CSharp\nvar container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Use the Container Singleton lifetime\n    .Bind\u003cIService\u003e().As(ContainerSingleton).To\u003cService\u003e()\n    .Container;\n\n// Resolve the container singleton twice\nvar instance1 = container.Resolve\u003cIService\u003e();\nvar instance2 = container.Resolve\u003cIService\u003e();\n\n// Check that instances from the parent container are equal\ninstance1.ShouldBe(instance2);\n\n// Create a child container\nvar childContainer = container.Create();\n\n// Resolve the container singleton twice\nvar childInstance1 = childContainer.Resolve\u003cIService\u003e();\nvar childInstance2 = childContainer.Resolve\u003cIService\u003e();\n\n// Check that instances from the child container are equal\nchildInstance1.ShouldBe(childInstance2);\n\n// Check that instances from different containers are not equal\ninstance1.ShouldNotBe(childInstance1);\n\n// Dispose instances on disposing a child container\nchildContainer.Dispose();\n((Service)childInstance1).DisposeCount.ShouldBe(1);\n((Service)childInstance2).DisposeCount.ShouldBe(1);\n((Service)instance1).DisposeCount.ShouldBe(0);\n((Service)instance2).DisposeCount.ShouldBe(0);\n\n// Dispose instances on disposing a container\ncontainer.Dispose();\n((Service)childInstance1).DisposeCount.ShouldBe(1);\n((Service)childInstance2).DisposeCount.ShouldBe(1);\n((Service)instance1).DisposeCount.ShouldBe(1);\n((Service)instance2).DisposeCount.ShouldBe(1);\n```\n\n\n\n### Disposing lifetime [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/DisposingLifetime.cs)\n\n\n\n``` CSharp\nvar container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Use the Disposing lifetime\n    .Bind\u003cIService\u003e().As(Disposing).To\u003cService\u003e()\n    .Container;\n\nvar instance = container.Resolve\u003cIService\u003e();\n\n// Dispose instances on disposing a container\ncontainer.Dispose();\n((Service)instance).DisposeCount.ShouldBe(1);\n```\n\n\n\n### Scope Root lifetime [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ScopeRootLifetime.cs)\n\nScopeRoot lifetime creates an instance together with new scope and allows control of all scope singletons by IScopeToken.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    // Bind \"session\" as a root of scope\n    .Bind\u003cSession\u003e().As(ScopeRoot).To\u003cSession\u003e()\n    // Bind a dependency as a container singleton\n    .Bind\u003cService\u003e().As(ContainerSingleton).To\u003cService\u003e()\n    // It is optional. Bind IDisposable to IScopeToken to prevent any reference to IoC types from models\n    .Bind\u003cIDisposable\u003e().To(ctx =\u003e ctx.Container.Inject\u003cIScopeToken\u003e())\n    .Container;\n\n// Resolve 2 sessions in own scopes\nvar session1 = container.Resolve\u003cSession\u003e();\nvar session2 = container.Resolve\u003cSession\u003e();\n\n// Check sessions are not equal\nsession1.ShouldNotBe(session2);\n\n// Check singletons are equal in the first scope \nsession1.Service1.ShouldBe(session1.Service2);\n\n// Check singletons are equal in the second scope\nsession2.Service1.ShouldBe(session2.Service2);\n\n// Check singletons are not equal for different scopes\nsession1.Service1.ShouldNotBe(session2.Service1);\n\n// Dispose of the instance from the first scope\nsession1.Dispose();\n\n// Check dependencies are disposed for the first scope\nsession1.Service1.DisposeCounter.ShouldBe(1);\n\n// Dispose container\ncontainer.Dispose();\n\n// Check all dependencies are disposed for the all scopes\nsession2.Service1.DisposeCounter.ShouldBe(1);\nsession1.Service1.DisposeCounter.ShouldBe(1);\nclass Service: IDisposable\n{\n    public int DisposeCounter;\n\n    public void Dispose() =\u003e DisposeCounter++;\n}\n\nclass Session: IDisposable\n{\n    private readonly IDisposable _scope;\n    public readonly Service Service1;\n    public readonly Service Service2;\n\n    public Session(\n        // There is no reference to the IoC type here\n        IDisposable scope,\n        Service service1,\n        Service service2)\n    {\n        _scope = scope;\n        Service1 = service1;\n        Service2 = service2;\n    }\n\n    public void Dispose() =\u003e _scope.Dispose();\n}\n```\n\n\n\n### Singleton lifetime [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/SingletonLifetime.cs)\n\n[Singleton](https://en.wikipedia.org/wiki/Singleton_pattern) is a design pattern that supposes for having only one instance of some class during the whole application lifetime. The main complaint about Singleton is that it contradicts the Dependency Injection principle and thus hinders testability. It essentially acts as a global constant, and it is hard to substitute it with a test when needed. The _Singleton lifetime_ is indispensable in this case.\n\n``` CSharp\nvar container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Use the Singleton lifetime\n    .Bind\u003cIService\u003e().As(Singleton).To\u003cService\u003e()\n    .Container;\n\n// Resolve the singleton twice\nvar instance1 = container.Resolve\u003cIService\u003e();\nvar instance2 = container.Resolve\u003cIService\u003e();\n\n// Check that instances from the parent container are equal\ninstance1.ShouldBe(instance2);\n\n// Create a child container\nusing var childContainer = container.Create();\n\n// Resolve the singleton twice\nvar childInstance1 = childContainer.Resolve\u003cIService\u003e();\nvar childInstance2 = childContainer.Resolve\u003cIService\u003e();\n\n// Check that instances from the child container are equal\nchildInstance1.ShouldBe(childInstance2);\n\n// Check that instances from different containers are equal\ninstance1.ShouldBe(childInstance1);\n\n// Dispose of instances on disposing of a container\ncontainer.Dispose();\n((Service)childInstance1).DisposeCount.ShouldBe(1);\n((Service)childInstance2).DisposeCount.ShouldBe(1);\n((Service)instance1).DisposeCount.ShouldBe(1);\n((Service)instance2).DisposeCount.ShouldBe(1);\n```\n\nThe lifetime could be:\n- _Transient_ - a new instance is creating each time (it's default lifetime)\n- [_Singleton_](https://en.wikipedia.org/wiki/Singleton_pattern) - single instance\n- _ContainerSingleton_ - singleton per container\n- _ScopeSingleton_ - singleton per scope\n- _ScopeRoot_ - root of a scope\n- _Disposing_ - Automatically calls a Disposable() method for disposable instances\n\n### Replacement of Lifetime [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ReplaceLifetime.cs)\n\nIt is possible to replace default lifetimes on your own one. The sample below shows how to count the number of attempts to resolve [singleton](https://en.wikipedia.org/wiki/Singleton_pattern) instances.\n\n``` CSharp\npublic void Run()\n{\n    var counter = new Mock\u003cICounter\u003e();\n\n    using var container = Container\n        .Create()\n        .Bind\u003cICounter\u003e().To(ctx =\u003e counter.Object)\n        // Replace the Singleton lifetime with a custom lifetime\n        .Bind\u003cILifetime\u003e().Tag(Lifetime.Singleton).To\u003cMySingletonLifetime\u003e(\n            // Select the constructor\n            ctx =\u003e new MySingletonLifetime(\n                // Inject the singleton lifetime from the parent container for partially delegating logic\n                ctx.Container.Parent.Inject\u003cILifetime\u003e(Lifetime.Singleton),\n                // Inject a counter to store the number of created instances\n                ctx.Container.Inject\u003cICounter\u003e()))\n        // Configure the container as usual\n        .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n        // Bind using the custom implementation of Singleton lifetime\n        .Bind\u003cIService\u003e().As(Lifetime.Singleton).To\u003cService\u003e()\n        .Container;\n\n    // Resolve the singleton twice using the custom lifetime\n    var instance1 = container.Resolve\u003cIService\u003e();\n    var instance2 = container.Resolve\u003cIService\u003e();\n\n    // Check that instances are equal\n    instance1.ShouldBe(instance2);\n\n    // Check the number of created instances\n    counter.Verify(i =\u003e i.Increment(), Times.Exactly(2));\n}\n\n// Represents the instance counter\npublic interface ICounter\n{\n    void Increment();\n}\n\npublic class MySingletonLifetime : ILifetime\n{\n    // Stores 'IncrementCounter' method info to the static field\n    private static readonly MethodInfo IncrementCounterMethodInfo = typeof(MySingletonLifetime).GetTypeInfo().DeclaredMethods.Single(i =\u003e i.Name == nameof(IncrementCounter));\n\n    private readonly ILifetime _baseSingletonLifetime;\n    private readonly ICounter _counter;\n\n    // Stores the base lifetime and the instance counter\n    public MySingletonLifetime(ILifetime baseSingletonLifetime, ICounter counter)\n    {\n        _baseSingletonLifetime = baseSingletonLifetime;\n        _counter = counter;\n    }\n\n    public Expression Build(IBuildContext context, Expression expression)\n    {\n        // Builds expression using base lifetime\n        expression = _baseSingletonLifetime.Build(context, expression);\n\n        // Defines `this` variable to store the reference to the current lifetime instance to call internal method 'IncrementCounter'\n        var thisVar = Expression.Constant(this);\n\n        // Creates a code block\n        return Expression.Block(\n            // Adds the expression to call the method 'IncrementCounter' for the current lifetime instance\n            Expression.Call(thisVar, IncrementCounterMethodInfo),\n            // Returns the expression to create an instance\n            expression);\n    }\n\n    // Creates a similar lifetime to use with generic instances\n    public ILifetime CreateLifetime() =\u003e new MySingletonLifetime(_baseSingletonLifetime.CreateLifetime(), _counter);\n\n    // Select a container to resolve dependencies using the Singleton lifetime logic\n    public IContainer SelectContainer(IContainer registrationContainer, IContainer resolvingContainer) =\u003e\n        _baseSingletonLifetime.SelectContainer(registrationContainer, resolvingContainer);\n\n    // Disposes the instance of the Singleton lifetime\n    public void Dispose() =\u003e _baseSingletonLifetime.Dispose();\n\n    // Just counts the number of requested instances\n    internal void IncrementCounter() =\u003e _counter.Increment();\n}\n```\n\n\n\n### Custom lifetime: thread Singleton [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ThreadSingletonLifetime.cs)\n\nSometimes it is useful to have a [singleton](https://en.wikipedia.org/wiki/Singleton_pattern) instance per a thread (or more generally a singleton per something else). There is no special \"lifetime\" type in this framework to achieve this requirement. Still, it is quite easy to create your own \"lifetime\" type for that using base type [_KeyBasedLifetime\u003c\u003e_](IoC/Lifetimes/KeyBasedLifetime.cs).\n\n``` CSharp\npublic void Run()\n{\n    var finish = new ManualResetEvent(false);\n    \n    var container = Container\n        .Create()\n        .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n        // Bind an interface to an implementation using the singleton per a thread lifetime\n        .Bind\u003cIService\u003e().Lifetime(new ThreadLifetime()).To\u003cService\u003e()\n        .Container;\n\n    // Resolve the singleton twice\n    var instance1 = container.Resolve\u003cIService\u003e();\n    var instance2 = container.Resolve\u003cIService\u003e();\n    IService instance3 = null;\n    IService instance4 = null;\n\n    var newThread = new Thread(() =\u003e\n    {\n        instance3 = container.Resolve\u003cIService\u003e();\n        instance4 = container.Resolve\u003cIService\u003e();\n        finish.Set();\n    });\n\n    newThread.Start();\n    finish.WaitOne();\n\n    // Check that instances resolved in a main thread are equal\n    instance1.ShouldBe(instance2);\n\n    // Check that instance resolved in a new thread is not null\n    instance3.ShouldNotBeNull();\n\n    // Check that instances resolved in different threads are not equal\n    instance1.ShouldNotBe(instance3);\n\n    // Check that instances resolved in a new thread are equal\n    instance4.ShouldBe(instance3);\n}\n\n// Represents the custom thread singleton lifetime based on the KeyBasedLifetime\npublic sealed class ThreadLifetime : KeyBasedLifetime\u003cint\u003e\n{\n    // Creates a clone of the current lifetime (for the case with generic types)\n    public override ILifetime CreateLifetime() =\u003e\n        new ThreadLifetime();\n\n    // Provides an instance key. In this case, it is just a thread identifier.\n    // If a key the same an instance is the same too.\n    protected override int CreateKey(IContainer container, object[] args) =\u003e\n        Thread.CurrentThread.ManagedThreadId;\n}\n```\n\n\n\n### Arrays [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Arrays.cs)\n\nTo resolve all possible instances of any tags of the specific type as an _array_ just use the injection _T[]_\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind to the implementation #1\n    .Bind\u003cIService\u003e().Tag(1).To\u003cService\u003e()\n    // Bind to the implementation #2\n    .Bind\u003cIService\u003e().Tag(2).Tag(\"abc\").To\u003cService\u003e()\n    // Bind to the implementation #3\n    .Bind\u003cIService\u003e().Tag(3).To\u003cService\u003e()\n    .Container;\n\n// Resolve all appropriate instances\nvar instances = container.Resolve\u003cIService[]\u003e();\n```\n\n\n\n### Collections [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Collections.cs)\n\nTo resolve all possible instances of any tags of the specific type as a _collection_ just use the injection _ICollection\u003cT\u003e_\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind to the implementation #1\n    .Bind\u003cIService\u003e().Tag(1).To\u003cService\u003e()\n    // Bind to the implementation #2\n    .Bind\u003cIService\u003e().Tag(2).Tag(\"abc\").To\u003cService\u003e()\n    // Bind to the implementation #3\n    .Bind\u003cIService\u003e().Tag(3).To\u003cService\u003e()\n    .Container;\n\n// Resolve all appropriate instances\nvar instances = container.Resolve\u003cICollection\u003cIService\u003e\u003e();\n\n// Check the number of resolved instances\ninstances.Count.ShouldBe(3);\n```\n\n\n\n### Enumerables [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Enumerables.cs)\n\nTo resolve all possible instances of any tags of the specific type as an _enumerable_ just use the injection _IEnumerable\u003cT\u003e_.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind to the implementation #1\n    .Bind\u003cIService\u003e().Tag(1).To\u003cService\u003e()\n    // Bind to the implementation #2\n    .Bind\u003cIService\u003e().Tag(2).Tag(\"abc\").To\u003cService\u003e()\n    // Bind to the implementation #3\n    .Bind\u003cIService\u003e().Tag(3).To\u003cService\u003e()\n    .Container;\n\n// Resolve all appropriate instances\nvar instances = container.Resolve\u003cIEnumerable\u003cIService\u003e\u003e().ToList();\n\n// Check the number of resolved instances\ninstances.Count.ShouldBe(3);\n```\n\n\n\n### Funcs [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Funcs.cs)\n\n_Func\u003c\u003e_ helps when a logic needs to inject some type of instances on-demand or solve circular dependency issues.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    .Bind\u003cIService\u003e().To\u003cService\u003e()\n    .Container;\n\n// Resolve function to create instances\nvar factory = container.Resolve\u003cFunc\u003cIService\u003e\u003e();\n\n// Resolve few instances\nvar instance1 = factory();\nvar instance2 = factory();\n```\n\n\n\n### Lazy [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Lazy.cs)\n\n_Lazy_ dependency helps when a logic needs to inject _Lazy\u003cT\u003e_ to get instance once on demand.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    .Bind\u003cIService\u003e().To\u003cService\u003e()\n    .Container;\n\n// Resolve the instance of Lazy\u003cIService\u003e\nvar lazy = container.Resolve\u003cLazy\u003cIService\u003e\u003e();\n\n// Get the instance via Lazy\nvar instance = lazy.Value;\n```\n\n\n\n### Nullable value type [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/NullableValueType.cs)\n\n\n\n``` CSharp\nusing var container = Container.Create()\n    .Bind\u003cint\u003e().Tag(1).To(ctx =\u003e 1)\n    .Container;\n\n// Resolve an instance\nvar val1 = container.Resolve\u003cint?\u003e(1.AsTag());\nvar val2 = container.Resolve\u003cint?\u003e(2.AsTag());\nvar val3 = container.Resolve\u003cint?\u003e();\n\n// Check the optional dependency\nval1.Value.ShouldBe(1);\nval2.HasValue.ShouldBeFalse();\nval3.HasValue.ShouldBeFalse();\n```\n\n\n\n### Observables [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Observables.cs)\n\nTo resolve all possible instances of any tags of the specific type as an _IObservable\u003c\u003e_ instance just use the injection _IObservable\u003cT\u003e_\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind to the implementation #1\n    .Bind\u003cIService\u003e().Tag(1).To\u003cService\u003e()\n    // Bind to the implementation #2\n    .Bind\u003cIService\u003e().Tag(2).Tag(\"abc\").To\u003cService\u003e()\n    // Bind to the implementation #3\n    .Bind\u003cIService\u003e().Tag(3).To\u003cService\u003e()\n    .Container;\n\n// Resolve the source for all appropriate instances\nvar instancesSource = container.Resolve\u003cIObservable\u003cIService\u003e\u003e();\n```\n\n\n\n### Sets [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Sets.cs)\n\nTo resolve all possible instances of any tags of the specific type as a _ISet\u003c\u003e_ just use the injection _ISet\u003cT\u003e_.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind to the implementation #1\n    .Bind\u003cIService\u003e().Tag(1).To\u003cService\u003e()\n    // Bind to the implementation #2\n    .Bind\u003cIService\u003e().Tag(2).Tag(\"abc\").To\u003cService\u003e()\n    // Bind to the implementation #3\n    .Bind\u003cIService\u003e().Tag(3).To\u003cService\u003e()\n    .Container;\n\n// Resolve all appropriate instances\nvar instances = container.Resolve\u003cISet\u003cIService\u003e\u003e();\n\n// Check the number of resolved instances\ninstances.Count.ShouldBe(3);\n```\n\n\n\n### ThreadLocal [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ThreadLocal.cs)\n\n\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    .Bind\u003cIService\u003e().To\u003cService\u003e()\n    .Container;\n\n// Resolve the instance of ThreadLocal\u003cIService\u003e\nvar threadLocal = container.Resolve\u003cThreadLocal\u003cIService\u003e\u003e();\n\n// Get the instance via ThreadLocal\nvar instance = threadLocal.Value;\n```\n\n\n\n### Tuples [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Tuples.cs)\n\n[Tuple](https://docs.microsoft.com/en-us/dotnet/api/system.tuple) has a set of elements that should be resolved at the same time.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    .Bind\u003cIService\u003e().To\u003cService\u003e()\n    .Bind\u003cINamedService\u003e().To\u003cNamedService\u003e(ctx =\u003e new NamedService(ctx.Container.Inject\u003cIDependency\u003e(), \"some name\"))\n    .Container;\n\n// Resolve an instance of type Tuple\u003cIService, INamedService\u003e\nvar tuple = container.Resolve\u003cTuple\u003cIService, INamedService\u003e\u003e();\n```\n\n\n\n### Value Tuples [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ValueTuples.cs)\n\n\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    .Bind\u003cIService\u003e().To\u003cService\u003e()\n    .Bind\u003cINamedService\u003e().To\u003cNamedService\u003e(ctx =\u003e new NamedService(ctx.Container.Inject\u003cIDependency\u003e(), \"some name\"))\n    .Container;\n{\n    // Resolve an instance of type (IService service, INamedService namedService)\n    var valueTuple = container.Resolve\u003c(IService service, INamedService namedService)\u003e();\n}\n\n```\n\n\n\n### Func with arguments [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/FuncWithArguments.cs)\n\nIt is easy to use _Func\u003c..., T\u003e_ with arguments and to pass these arguments to the created instances manually via context arguments.\n\n``` CSharp\nFunc\u003cIDependency, string, INamedService\u003e func = \n    (dependency, name) =\u003e new NamedService(dependency, name);\n\n// Create and configure the container, using full autowiring\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind the constructor and inject argument[0] as the second parameter of type 'string'\n    .Bind\u003cINamedService\u003e().To(ctx =\u003e func(ctx.Container.Inject\u003cIDependency\u003e(), (string)ctx.Args[0]))\n    .Container;\n\n// Resolve the instance passing the string \"alpha\" into the array of arguments\nvar instance = container.Resolve\u003cINamedService\u003e(\"alpha\");\n\n// Check the instance's type\ninstance.ShouldBeOfType\u003cNamedService\u003e();\n\n// Check that argument \"alpha\" was used during the construction of an instance\ninstance.Name.ShouldBe(\"alpha\");\n\n// Resolve a factory\nvar factory = container.Resolve\u003cFunc\u003cstring, INamedService\u003e\u003e();\n\n// Run this function and pass the string \"beta\" as argument\nvar otherInstance = factory(\"beta\");\n\n// Check that argument \"beta\" was used during constructing an instance\notherInstance.Name.ShouldBe(\"beta\");\n```\n\nBesides that, you can rely on full autowring, when it is not needed to specify constructor arguments at all. In this case, all appropriate arguments are matching with context arguments automatically by type.\n\n### ValueTask [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/AsynchronousValueResolve.cs)\n\nIn this scenario, ValueTask is just a container for a resolved instance.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind Service\n    .Bind\u003cIService\u003e().To\u003cService\u003e()\n    .Container;\n\n// Resolve an instance asynchronously via ValueTask\nvar instance = await container.Resolve\u003cValueTask\u003cIService\u003e\u003e();\n```\n\n\n\n### Async Enumerables [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/AsyncEnumerables.cs)\n\nIt is easy to resolve an enumerator [IAsyncEnumerable\u003c\u003e](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.iasyncenumerable-1) that provides asynchronous iteration over values of a type for every tag.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Using(CollectionFeature.Set)\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    // Bind to the default implementation\n    .Bind\u003cIService\u003e().To\u003cService\u003e()\n    // Bind to the implementation #1\n    .Bind\u003cIService\u003e().Tag(1).To\u003cService\u003e()\n    // Bind to the implementation #2\n    .Bind\u003cIService\u003e().Tag(2).Tag(\"abc\").To\u003cService\u003e()\n    // Bind to the implementation #3\n    .Bind\u003cIService\u003e().Tag(3).To\u003cService\u003e()\n    .Container;\n\n// Resolve all appropriate instances\nvar instances = container.Resolve\u003cIAsyncEnumerable\u003cIService\u003e\u003e();\nvar items = new List\u003cIService\u003e();\nawait foreach (var instance in instances) { items.Add(instance); }\n\n// Check the number of resolved instances\nitems.Count.ShouldBe(4);\n\n```\n\n\n\n### Asynchronous construction [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/AsynchronousConstruction.cs)\n\nIt is easy to inject dependencies in an asynchronous style.\n\n``` CSharp\npublic async void Run()\n{\n    using var container = Container.Create()\n        // Bind some dependency\n        .Bind\u003cIDependency\u003e().To\u003cSomeDependency\u003e()\n        .Bind\u003cConsumer\u003e().To\u003cConsumer\u003e()\n        .Container;\n\n    // Resolve an instance asynchronously using the default task scheduler _TaskScheduler.Current_\n    var instance = await container.Resolve\u003cTask\u003cConsumer\u003e\u003e();\n\n    // Check the instance\n    instance.ShouldBeOfType\u003cConsumer\u003e();\n}\n\npublic class SomeDependency: IDependency\n{\n    // Some time-consuming constructor\n    public SomeDependency() { }\n\n    public int Index { get; set; }\n}\n\npublic class Consumer\n{\n    public Consumer(Task\u003cIDependency\u003e dependency1, Task\u003cIDependency\u003e dependency2)\n    {\n        // Some time-consuming statements\n        var dep1 = dependency1.Result;\n        var dep2 = dependency2.Result;\n    }\n}\n```\n\nIt is better to not use any logic except an instance field setup logic within a constructor.\n\n### Cancellation of asynchronous construction [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/AsynchronousConstructionCancellation.cs)\n\nIt is possible to inject dependencies in asynchronous style and to cancel their creations using default _CancellationTokenSource_.\n\n``` CSharp\npublic void Run()\n{\n    // Create a cancellation token source\n    var cancellationTokenSource = new CancellationTokenSource();\n\n    using var container = Container.Create()\n        // Bind cancellation token source\n        .Bind\u003cCancellationTokenSource\u003e().To(ctx =\u003e cancellationTokenSource)\n        // Bind the cancellation token\n        .Bind\u003cCancellationToken\u003e().To(ctx =\u003e ctx.Container.Inject\u003cCancellationTokenSource\u003e().Token)\n        // Bind some dependency\n        .Bind\u003cIDependency\u003e().To\u003cSomeDependency\u003e()\n        .Bind\u003cConsumer\u003e().To\u003cConsumer\u003e()\n        .Container;\n\n    // Resolve an instance asynchronously\n    var instanceTask = container.Resolve\u003cTask\u003cConsumer\u003e\u003e();\n\n    // Cancel tasks\n    cancellationTokenSource.Cancel();\n\n    // Get an instance\n    instanceTask.Result.ShouldBeOfType\u003cConsumer\u003e();\n}\n\npublic class SomeDependency: IDependency\n{\n    // A time-consuming logic constructor with \n    public SomeDependency(CancellationToken cancellationToken)\n    {\n        while (!cancellationToken.IsCancellationRequested) { }\n    }\n\n    public int Index { get; set; }\n}\n\npublic class Consumer\n{\n    public Consumer(Task\u003cIDependency\u003e dependency1, Task\u003cIDependency\u003e dependency2)\n    {\n        // A time-consuming logic\n        var dep1 = dependency1.Result;\n        var dep2 = dependency2.Result;\n    }\n}\n```\n\n\n\n### Override the default task scheduler [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/TaskSchedulerOverride.cs)\n\n_TaskScheduler.Current_ is used by default for an asynchronous construction, but it is easy to override it, binding abstract class _TaskScheduler_ to required implementation in an IoC container.\n\n``` CSharp\nusing var container = Container.Create()\n    // Bind some dependency\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    .Bind\u003cIService\u003e().To\u003cService\u003e()\n    // Override the default _TaskScheduler by your own one\n    .Bind\u003cTaskScheduler\u003e().To(ctx =\u003e TaskScheduler.Default)\n    .Container;\n\n// Resolve an instance asynchronously\nvar instance = await container.Resolve\u003cTask\u003cIService\u003e\u003e();\n```\n\n\n\n### Change configuration on-the-fly [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ChangeConfigurationOnTheFly.cs)\n\n\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    .Container;\n\n// Configure `IService` as Transient\nusing (container.Bind\u003cIService\u003e().To\u003cService\u003e())\n{\n    // Resolve instances\n    var instance1 = container.Resolve\u003cIService\u003e();\n    var instance2 = container.Resolve\u003cIService\u003e();\n\n    // Check that instances are not equal\n    instance1.ShouldNotBe(instance2);\n}\n\n// Reconfigure `IService` as Singleton\nusing (container.Bind\u003cIService\u003e().As(Lifetime.Singleton).To\u003cService\u003e())\n{\n    // Resolve the singleton twice\n    var instance1 = container.Resolve\u003cIService\u003e();\n    var instance2 = container.Resolve\u003cIService\u003e();\n\n    // Check that instances are equal\n    instance1.ShouldBe(instance2);\n}\n```\n\n\n\n### Resolve Unbound for abstractions [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ResolveUnboundForAbstractions.cs)\n\nThe feature _ResolveUnboundFeature_ allows you to resolve any implementation type from the container regardless of whether or not you specifically bound it and find appropriate implementations for abstractions using a key \"resolver\".\n\n``` CSharp\npublic void Run()\n{\n    using var container = Container\n        .Create()\n        .Using(new ResolveUnboundFeature(KeyResolver));\n\n    // Resolve an instance of unregistered type\n    container.Resolve\u003cIService\u003e();\n}\n\n// Find an appropriate implementation using all non-abstract types defined in the current assembly\nprivate static Key KeyResolver(Key key) =\u003e\n    new Key((\n        from type in key.Type.Assembly.GetTypes()\n        where !type.IsInterface \n        where !type.IsAbstract\n        where key.Type.IsAssignableFrom(type)\n        select type).FirstOrDefault() ?? throw new InvalidOperationException($\"Cannot find a type assignable to {key}.\"),\n        key.Tag);\n\n```\n\n\n\n### Constructor choice [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ConstructorChoice.cs)\n\nWe can specify a constructor manually and all its arguments.\n\n``` CSharp\nusing var container = Container\n    .Create()\n    .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n    .Bind\u003cIService\u003e().To\u003cService\u003e(\n        // Select the constructor and inject required dependencies\n        ctx =\u003e new Service(ctx.Container.Inject\u003cIDependency\u003e(), \"some state\"))\n    .Container;\n\nvar instance = container.Resolve\u003cIService\u003e();\n\n// Check the injected constant\ninstance.State.ShouldBe(\"some state\");\n```\n\n\n\n### Container injection [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ContainerInjection.cs)\n\n:warning: Please avoid injecting containers in non-infrastructure code. Keep your code in ignorance about a container framework.\n\n``` CSharp\npublic void Run()\n{\n    using var currentContainer = Container\n        .Create(\"root\")\n        .Bind\u003cMyClass\u003e().To\u003cMyClass\u003e()\n        .Container;\n\n    var instance = currentContainer.Resolve\u003cMyClass\u003e();\n    instance.CurrentContainer.ShouldBe(currentContainer);\n    instance.ChildContainer1.Parent.ShouldBe(currentContainer);\n    instance.ChildContainer2.Parent.ShouldBe(currentContainer);\n    instance.NamedChildContainer.Parent.ShouldBe(currentContainer);\n    instance.NamedChildContainer.ToString().ShouldBe(\"//root/Some name\");\n}\n\npublic class MyClass\n{\n    public MyClass(\n        IContainer currentContainer,\n        IMutableContainer newChildContainer,\n        Func\u003cIMutableContainer\u003e childContainerFactory,\n        Func\u003cstring, IMutableContainer\u003e nameChildContainerFactory)\n    {\n        CurrentContainer = currentContainer;\n        ChildContainer1 = newChildContainer;\n        ChildContainer2 = childContainerFactory();\n        NamedChildContainer = nameChildContainerFactory(\"Some name\");\n    }\n\n    public IContainer CurrentContainer { get; }\n\n    public IContainer ChildContainer1 { get; }\n\n    public IContainer ChildContainer2 { get; }\n\n    public IContainer NamedChildContainer { get; }\n}\n```\n\n\n\n### Tracing [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Tracing.cs)\n\nTracing allows to explore most aspects of container behavior: creating and removing child containers, adding and removing bindings, compiling instance factories.\n\n``` CSharp\nvar traceMessages = new List\u003cstring\u003e();\n\n// This block is just to mark the scope for \"using\" statements\n{\n    // Create and configure a root container\n    using var rootContainer = Container\n        .Create(\"root\")\n        // Aggregate trace messages to the list 'traceMessages'\n        .Trace(e =\u003e traceMessages.Add(e.Message))\n        .Container;\n\n    // Create and configure a parent container\n    using var parentContainer = rootContainer\n        .Create(\"parent\")\n        .Bind\u003cIDependency\u003e().To\u003cDependency\u003e(ctx =\u003e new Dependency())\n        .Container;\n\n    // Create and configure a child container\n    using var childContainer = parentContainer\n        .Create(\"child\")\n        .Bind\u003cIService\u003cTT\u003e\u003e().To\u003cService\u003cTT\u003e\u003e()\n        .Container;\n\n    childContainer.Resolve\u003cIService\u003cint\u003e\u003e();\n} // All containers were disposed of here\n\ntraceMessages.Count.ShouldBe(8);\n```\n\n\n\n### Check a binding [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ValidateBinding.cs)\n\nIt is easy to validate that binding already exists.\n\n``` CSharp\nusing var container = Container.Create();\n\nvar isBound = container.IsBound\u003cIService\u003e();\n// _IService_ is not bound yet\nisBound.ShouldBeFalse();\n\ncontainer.Bind\u003cIService\u003e().To\u003cService\u003e();\n\n// _IService_ is already bound\nisBound = container.IsBound\u003cIService\u003e();\n\nisBound.ShouldBeTrue();\n```\n\n\n\n### Check for possible resolving [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/ValidateResolving.cs)\n\nIt is easy to validate the ability to resolve something without resolving it.\n\n``` CSharp\n// Create and configure a container\nusing var container = Container\n    .Create()\n    .Bind\u003cIService\u003e().To\u003cService\u003e()\n    .Container;\n\n// _Service_ has the mandatory dependency _IDependency_ in the constructor,\n// which was not registered and that is why _IService_ cannot be resolved\ncontainer.CanResolve\u003cIService\u003e().ShouldBeFalse();\n\n// Add the required binding for _Service_\ncontainer.Bind\u003cIDependency\u003e().To\u003cDependency\u003e();\n\n// Now it is possible to resolve _IService_\ncontainer.CanResolve\u003cIService\u003e().ShouldBeTrue();\n```\n\n\n\n### Custom builder [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/CustomBuilder.cs)\n\nThe sample below shows how to use this extension point [_IBuilder_](IoCContainer/blob/master/IoC/IBuilder.cs) to rewrite the expression tree of creation any instances to check constructor arguments on null. It is possible to create other own builders to make any manipulation on expression trees before they will be compiled into factories for the creation of the instances. Any logic any automation - checking arguments, logging, thread safety, authorization aspects and etc.\n\n``` CSharp\npublic void Run()\n{\n    using var container = Container\n        .Create()\n        .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n        .Bind\u003cIService\u003e().To\u003cService\u003e(ctx =\u003e new Service(ctx.Container.Resolve\u003cIDependency\u003e(), ctx.Args[0] as string))\n        // Register the custom builder\n        .Bind\u003cIBuilder\u003e().To\u003cNotNullGuardBuilder\u003e()\n        .Container;\n\n    // Resolve an instance passing null to the \"state\" parameter\n    Assert.Throws\u003cArgumentNullException\u003e(() =\u003e container.Resolve\u003cIService\u003e(null as string));\n}\n\n// This custom builder adds the logic to check parameters of reference types injected via constructors on null\nprivate class NotNullGuardBuilder : IBuilder\n{\n    public Expression Build(IBuildContext context, Expression expression) =\u003e\n        expression is NewExpression newExpression \u0026\u0026 newExpression.Arguments.Count != 0\n            ? newExpression.Update(CheckedArgs(newExpression))\n            : expression;\n\n    private static IEnumerable\u003cExpression\u003e CheckedArgs(NewExpression newExpression) =\u003e\n        from arg in newExpression.Constructor.GetParameters().Select((info, index) =\u003e (info, expression: newExpression.Arguments[index]))\n        let typeDescriptor = arg.info.ParameterType.Descriptor()\n        select !typeDescriptor.IsValueType()\n            // arg ?? throw new ArgumentNullException(nameof(arg), \"The argument ...\")\n            ? Expression.Coalesce(\n                arg.expression,\n                // Throws an exception when an argument is null\n                Expression.Block(\n                    Expression.Throw(Expression.Constant(new ArgumentNullException(arg.info.Name, $\"The argument \\\"{arg.info.Name}\\\" is null while constructing the instance of type \\\"{newExpression.Type.Name}\\\".\"))),\n                    Expression.Default(typeDescriptor.Type)))\n            : arg.expression;\n}\n```\n\n\n\n### Custom child container [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/CustomChildContainer.cs)\n\nYou may replace the default implementation of the container with your own. I can't imagine why it should be done, but it’s possible!\n\n``` CSharp\npublic void Run()\n{\n    // Create and configure the root container\n    using var container = Container\n        .Create()\n        .Bind\u003cIService\u003e().To\u003cService\u003e()\n        // Configure the root container to use a custom container as a child container\n        .Bind\u003cIMutableContainer\u003e().To\u003cMyContainer\u003e()\n        .Container;\n\n    // Create and configure the custom child container\n    using var childContainer = container\n        .Create()\n        .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n        .Container;\n\n    // Resolve an instance\n    var instance = childContainer.Resolve\u003cIService\u003e();\n\n    // Check the child container type\n    childContainer.ShouldBeOfType\u003cMyContainer\u003e();\n}\n\n// Sample of transparent container implementation\npublic class MyContainer: IMutableContainer\n{\n    // Some implementation here\n}\n```\n\n\n\n### Interception [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Interception.cs)\n\nThe _Interception_ feature allows specifying the set of bindings that will be used to produce instances wrapped by proxy objects. These proxy objects intercept any invocations to the created (or injected) instances and allow to add any logic around it: checking arguments, logging, thread safety, authorization aspects and etc.\n\n``` CSharp\n// To use this feature please add the NuGet package https://www.nuget.org/packages/IoC.Interception\n// or https://www.nuget.org/packages/IoC.Interception.Source\npublic void Run()\n{\n    var methods = new List\u003cstring\u003e();\n    using var container = Container\n        // Creates the Inversion of Control container\n        .Create()\n        // Using the feature InterceptionFeature\n        .Using\u003cInterceptionFeature\u003e()\n        // Configures binds\n        .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n        .Bind\u003cIService\u003e().To\u003cService\u003e()\n        // Intercepts any invocations\n        .Intercept(key =\u003e true, new MyInterceptor(methods))\n        .Container;\n\n    // Resolve an instance\n    var instance = container.Resolve\u003cIService\u003e();\n\n    // Invoke the getter \"get_State\"\n    var state = instance.State;\n    instance.Dependency.Index = 1;\n\n    // Check invocations by our interceptor\n    methods.ShouldContain(\"get_State\");\n    methods.ShouldContain(\"set_Index\");\n}\n\n// This interceptor just stores names of called methods\npublic class MyInterceptor : IInterceptor\n{\n    private readonly ICollection\u003cstring\u003e _methods;\n\n    // Stores the collection of called method names\n    public MyInterceptor(ICollection\u003cstring\u003e methods) =\u003e _methods = methods;\n\n    // Intercepts the invocations and appends the called method name to the collection\n    public void Intercept(IInvocation invocation)\n    {\n        _methods.Add(invocation.Method.Name);\n        invocation.Proceed();\n    }\n}\n```\n\n\n\n### Custom autowiring strategy [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/OverrideAutowiringStrategy.cs)\n\n\n\n``` CSharp\npublic void Run()\n{\n    using var container = Container\n        .Create()\n        .Bind\u003cIDependency\u003e().To\u003cDependency\u003e()\n        // NamedService requires the \"name\" parameter of a String type in the constructor\n        .Bind\u003cINamedService\u003e().To\u003cNamedService\u003e()\n        // Overrides the previous autowiring strategy for the current and children containers\n        .Bind\u003cIAutowiringStrategy\u003e().To\u003cCustomAutowiringStrategy\u003e()\n        .Container;\n\n    var service = container.Resolve\u003cINamedService\u003e();\n\n    service.Name.ShouldBe(\"default name\");\n}\n\nclass CustomAutowiringStrategy : IAutowiringStrategy\n{\n    private readonly IAutowiringStrategy _baseStrategy;\n\n    public CustomAutowiringStrategy(IContainer container, IAutowiringStrategy baseStrategy) =\u003e\n        // Saves the previous autowiring strategy\n        _baseStrategy = baseStrategy;\n\n    public bool TryResolveType(IContainer container, Type registeredType, Type resolvingType, out Type instanceType) =\u003e\n        // Just uses logic from the previous autowiring strategy as is\n        _baseStrategy.TryResolveType(container, registeredType, resolvingType, out instanceType);\n\n    // Overrides logic to inject the constant \"default name\" to every constructor's parameters named \"name\" of type String\n    public bool TryResolveConstructor(IContainer container, IEnumerable\u003cIMethod\u003cConstructorInfo\u003e\u003e constructors, out IMethod\u003cConstructorInfo\u003e constructor)\n    {\n        if (!_baseStrategy.TryResolveConstructor(container, constructors, out constructor))\n        {\n            return false;\n        }\n\n        var selectedConstructor = constructor;\n        selectedConstructor.Info.GetParameters()\n            // Filters constructor parameters\n            .Where(p =\u003e p.Name == \"name\" \u0026\u0026 p.ParameterType == typeof(string)).ToList()\n            // Overrides every parameter's expression by the constant \"default name\"\n            .ForEach(p =\u003e selectedConstructor.SetExpression(p.Position, Expression.Constant(\"default name\")));\n\n        return true;\n    }\n\n    public bool TryResolveInitializers(IContainer container, IEnumerable\u003cIMethod\u003cMethodInfo\u003e\u003e methods, out IEnumerable\u003cIMethod\u003cMethodInfo\u003e\u003e initializers)\n        // Just uses logic from the previous autowiring strategy as is\n        =\u003e _baseStrategy.TryResolveInitializers(container, methods, out initializers);\n}\n```\n\n\n\n### Cyclic dependency [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/CyclicDependency.cs)\n\nBy default, a circular dependency is detected after the 256th recursive resolution. This behavior may be changed by overriding the interface _IFoundCyclicDependency_.\n\n``` CSharp\npublic void Run()\n{\n    var expectedException = new InvalidOperationException(\"error\");\n    var foundCyclicDependency = new Mock\u003cIFoundCyclicDependency\u003e();\n    // Throws the exception for reentrancy 128\n    foundCyclicDependency.Setup(i =\u003e i.Resolve(It.Is\u003cIBuildContext\u003e(ctx =\u003e ctx.Depth == 128))).Throws(expectedException);\n\n    using var container = Container\n        .Create()\n        .Bind\u003cIFoundCyclicDependency\u003e().To(ctx =\u003e foundCyclicDependency.Object)\n        // Configure the container, where 1,2,3 are tags to produce cyclic dependencies during a resolving\n        .Bind\u003cILink\u003e().To\u003cLink\u003e(ctx =\u003e new Link(ctx.Container.Inject\u003cILink\u003e(1)))\n        .Bind\u003cILink\u003e().Tag(1).To\u003cLink\u003e(ctx =\u003e new Link(ctx.Container.Inject\u003cILink\u003e(2)))\n        .Bind\u003cILink\u003e().Tag(2).To\u003cLink\u003e(ctx =\u003e new Link(ctx.Container.Inject\u003cILink\u003e(3)))\n        .Bind\u003cILink\u003e().Tag(3).To\u003cLink\u003e(ctx =\u003e new Link(ctx.Container.Inject\u003cILink\u003e(1)))\n        .Container;\n\n    try\n    {\n        // Resolve the root instance\n        container.Resolve\u003cILink\u003e();\n    }\n    // Catch the exception about cyclic dependencies at a depth of 128\n    catch (InvalidOperationException actualException)\n    {\n        // Check the exception\n        actualException.ShouldBe(expectedException);\n    }\n}\n\npublic interface ILink { }\n\npublic class Link : ILink\n{\n    public Link(ILink link) { }\n}\n```\n\n\n\n### Plugins [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Plugins.cs)\n\n\n\n``` CSharp\npublic void Run()\n{\n    // Given\n    var pluginTypes = new[] { typeof(Plugin1), typeof(Plugin2), typeof(Plugin3) };\n\n    using var container = Container.Create();\n    foreach (var pluginType in pluginTypes)\n    {\n        // Should ensure uniqueness of plugin\n        var uniquePluginId = pluginType;\n\n        // Bind several opened types by a tag which should ensure uniqueness of binding\n        container.Bind(typeof(IPlugin)).Tag(uniquePluginId).To(pluginType);\n    }\n\n    // When\n\n    // Resolve plugins\n    var plugins = container.Resolve\u003cIEnumerable\u003cIPlugin\u003e\u003e();\n\n    // This also works when you cannot use a generic type like IEnumerable\u003cIPlugin\u003e\n    // var plugins = container.Resolve\u003cIEnumerable\u003cobject\u003e\u003e(typeof(IEnumerable\u003c\u003e).MakeGenericType(typeof(IPlugin)));\n\n    // Then\n    var resolvedPluginTypes = plugins.Select(i =\u003e i.GetType()).ToList();\n\n    resolvedPluginTypes.Count.ShouldBe(3);\n\n    // We cannot rely on order here\n    resolvedPluginTypes.Contains(typeof(Plugin1)).ShouldBeTrue();\n    resolvedPluginTypes.Contains(typeof(Plugin2)).ShouldBeTrue();\n    resolvedPluginTypes.Contains(typeof(Plugin3)).ShouldBeTrue();\n}\n\ninterface IPlugin { }\n\nclass Plugin1 : IPlugin { }\n\nclass Plugin2 : IPlugin { }\n\nclass Plugin3 : IPlugin { }\n```\n\n\n\n### Generator sample [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Generator.cs)\n\n\n\n``` CSharp\npublic void Run()\n{\n    // Create and configure the container using a configuration class 'Generators'\n    using var container = Container.Create().Using\u003cGenerators\u003e();\n    using (container.Bind\u003c(int, int)\u003e().To(\n        // Uses a function to create a tuple because the expression trees have a limitation in syntax\n        ctx =\u003e System.ValueTuple.Create(\n            // The first one is of sequential number generator\n            ctx.Container.Inject\u003cint\u003e(GeneratorType.Sequential),\n            // The second one is of random number generator\n            ctx.Container.Inject\u003cint\u003e(GeneratorType.Random))))\n    {\n        // Generate sequential numbers\n        var sequential1 = container.Resolve\u003cint\u003e(GeneratorType.Sequential.AsTag());\n        var sequential2 = container.Resolve\u003cint\u003e(GeneratorType.Sequential.AsTag());\n\n        // Check numbers\n        sequential2.ShouldBe(sequential1 + 1);\n\n        // Generate a random number\n        var random = container.Resolve\u003cint\u003e(GeneratorType.Random.AsTag());\n\n        // Generate a tuple of numbers\n        var setOfValues = container.Resolve\u003c(int, int)\u003e();\n\n        // Check sequential numbers\n        setOfValues.Item1.ShouldBe(sequential2 + 1);\n    }\n}\n\n// Represents tags for generators\npublic enum GeneratorType\n{\n    Sequential, Random\n}\n\n// Represents IoC configuration\npublic class Generators: IConfiguration\n{\n    public IEnumerable\u003cIToken\u003e Apply(IMutableContainer container)\n    {\n        var value = 0;\n        // Define a function to get sequential integer value\n        Func\u003cint\u003e generator = () =\u003e Interlocked.Increment(ref value);\n        // Bind this function using the corresponding tag 'Sequential'\n        yield return container.Bind\u003cint\u003e().Tag(GeneratorType.Sequential).To(ctx =\u003e generator());\n\n        var random = new Random();\n        // Define a function to get random integer value\n        Func\u003cint\u003e randomizer = () =\u003e random.Next();\n        // Bind this function using the corresponding tag 'Random'\n        yield return container.Bind\u003cint\u003e().Tag(GeneratorType.Random).To(ctx =\u003e randomizer());\n    }\n}\n```\n\n\n\n### Wrapper sample [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Wrapper.cs)\n\n\n\n``` CSharp\npublic void Run()\n{\n    var console = new Mock\u003cIConsole\u003e();\n    var clock = new Mock\u003cIClock\u003e();\n    var now = new DateTimeOffset(2019, 9, 9, 12, 31, 34, TimeSpan.FromHours(3));\n    clock.SetupGet(i =\u003e i.Now).Returns(now);\n\n    // Create and configure a root container\n    using var rootContainer = Container\n        .Create(\"root\")\n        .Bind\u003cIConsole\u003e().To(ctx =\u003e console.Object)\n        .Bind\u003cILogger\u003e().To\u003cLogger\u003e()\n        .Container;\n\n    // Create and configure a child container\n    using var childContainer = rootContainer\n        .Create(\"child\")\n        .Bind\u003cIClock\u003e().To(ctx =\u003e clock.Object)\n        // Binds 'ILogger' to the instance creation, actually represented as an expression tree\n        // and injects the base logger from the parent container \"root\" and the clock from the current container \"child\"\n        .Bind\u003cILogger\u003e().To\u003cTimeLogger\u003e()\n        .Container;\n\n    // Create a logger\n    var logger = childContainer.Resolve\u003cILogger\u003e();\n\n    // Log the message\n    logger.Log(\"Hello\");\n\n    // Check the console output\n    console.Verify(i =\u003e i.WriteLine($\"{now}: Hello\"));\n}\n\npublic interface IConsole\n{\n    // Writes a text\n    void WriteLine(string text);\n}\n\npublic interface ILogger\n{\n    // Logs a message\n    void Log(string message);\n}\n\npublic interface IClock\n{\n    DateTimeOffset Now { get; }\n}\n\npublic class Logger : ILogger\n{\n    private readonly IConsole _console;\n\n    // Stores console to field\n    public Logger(IConsole console) =\u003e _console = console;\n\n    // Logs a message to console\n    public void Log(string message) =\u003e _console.WriteLine(message);\n}\n\npublic class TimeLogger: ILogger\n{\n    private readonly ILogger _baseLogger;\n    private readonly IClock _clock;\n\n    public TimeLogger(ILogger baseLogger, IClock clock)\n    {\n        _baseLogger = baseLogger;\n        _clock = clock;\n    }\n\n    // Adds current time as a message prefix and writes it to the console\n    public void Log(string message) =\u003e _baseLogger.Log($\"{_clock.Now}: {message}\");\n}\n```\n\n\n\n### Instant Messenger sample [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/SimpleInstantMessenger.cs)\n\n\n\n``` CSharp\npublic void Run()\n{\n    var observer = new Mock\u003cIObserver\u003cIMessage\u003e\u003e();\n\n    // Create a container\n    using var container = Container.Create().Using\u003cInstantMessengerConfig\u003e();\n\n    // Composition Root\n    // Resolve a messenger\n    var instantMessenger = container.Resolve\u003cIInstantMessenger\u003cIMessage\u003e\u003e();\n    using var subscription = instantMessenger.Subscribe(observer.Object);\n\n    // Send messages\n    instantMessenger.SendMessage(\"Nik\", \"John\", \"Hello, John\");\n    instantMessenger.SendMessage(\"John\", \"Nik\", \"Hello, Nik!\");\n\n    // Verify messages\n    observer.Verify(i =\u003e i.OnNext(It.Is\u003cIMessage\u003e(message =\u003e message.Id == 34 \u0026\u0026 message.Text == \"Hello, John\")));\n    observer.Verify(i =\u003e i.OnNext(It.Is\u003cIMessage\u003e(message =\u003e message.Id == 35 \u0026\u0026 message.Text == \"Hello, Nik!\")));\n}\n\npublic class InstantMessengerConfig: IConfiguration\n{\n    public IEnumerable\u003cIToken\u003e Apply(IMutableContainer container)\n    {\n        // Let's suppose that the initial message ID is 33\n        var id = 33;\n\n        yield return container\n            // id generator\n            .Bind\u003cint\u003e().To(ctx =\u003e Interlocked.Increment(ref id))\n            // abstract messenger\n            .Bind(typeof(IInstantMessenger\u003c\u003e)).To(typeof(InstantMessenger\u003c\u003e))\n            // abstract subject\n            .Bind\u003cISubject\u003cTT\u003e\u003e().To\u003cSubject\u003cTT\u003e\u003e()\n            // message factory\n            .Bind\u003cIMessageFactory\u003cIMessage\u003e\u003e().To\u003cMessage\u003e();\n    }\n}\n\npublic interface IInstantMessenger\u003cout T\u003e: IObservable\u003cT\u003e\n{\n    void SendMessage(string addressFrom, string addressTo, string text);\n}\n\npublic interface IMessage\n{\n    int Id { get; }\n\n    string AddressFrom { get; }\n\n    string AddressTo { get; }\n\n    string Text { get; }\n}\n\npublic interface IMessageFactory\u003cout T\u003e\n{\n    T Create([NotNull] string addressFrom, [NotNull] string addressTo, [NotNull] string text);\n}\n\npublic class Message: IMessage, IMessageFactory\u003cIMessage\u003e\n{\n    private readonly Func\u003cint\u003e _idFactory;\n\n    public Message(Func\u003cint\u003e idFactory) =\u003e _idFactory = idFactory;\n\n    private Message(int id, [NotNull] string addressFrom, [NotNull] string addressTo, [NotNull] string text)\n    {\n        Id = id;\n        AddressFrom = addressFrom ?? throw new ArgumentNullException(nameof(addressFrom));\n        AddressTo = addressTo ?? throw new ArgumentNullException(nameof(addressTo));\n        Text = text ?? throw new ArgumentNullException(nameof(text));\n    }\n\n    public int Id { get; }\n\n    public string AddressFrom { get; }\n\n    public string AddressTo { get; }\n\n    public string Text { get; }\n\n    public IMessage Create(string addressFrom, string addressTo, string text) =\u003e new Message(_idFactory(), addressFrom, addressTo, text);\n}\n\npublic class InstantMessenger\u003cT\u003e : IInstantMessenger\u003cT\u003e\n{\n    private readonly IMessageFactory\u003cT\u003e _messageFactory;\n    private readonly ISubject\u003cT\u003e _messages;\n\n    internal InstantMessenger(IMessageFactory\u003cT\u003e messageFactory, ISubject\u003cT\u003e subject)\n    {\n        _messageFactory = messageFactory;\n        _messages = subject;\n    }\n\n    public IDisposable Subscribe(IObserver\u003cT\u003e observer) =\u003e _messages.Subscribe(observer);\n\n    public void SendMessage(string addressFrom, string addressTo, string text) =\u003e _messages.OnNext(_messageFactory.Create(addressFrom, addressTo, text));\n}\n```\n\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevteam%2Fioccontainer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevteam%2Fioccontainer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevteam%2Fioccontainer/lists"}