Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/devteam/ioccontainer

Expressions based Inversion of Control container for .NET
https://github.com/devteam/ioccontainer

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

Last synced: 4 days ago
JSON representation

Expressions based Inversion of Control container for .NET

Awesome Lists containing this project

README

        

# Simple, powerful and fast Inversion of Control container for .NET

[![NuGet](https://buildstats.info/nuget/IoC.Container)](https://www.nuget.org/packages/IoC.Container)
[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
[](http://teamcity.jetbrains.com/viewType.html?buildTypeId=OpenSourceProjects_DevTeam_IoCContainer_BuildAndTest&guest=1)

#### Base concepts:

- maximum performance
- based on compiled expressions
- free of boxing and unboxing
- avoid using delegates

- thoughtful design
- code is fully independent of the IoC framework
- supports for BCL types out of the box
- ultra-fine tuning of generic types
- aspect-oriented DI
- predictable dependency graph
- _Func<... ,T>_ based factories passing a state

## [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)

### The reality is that

![Cat](https://github.com/DevTeam/IoCContainer/blob/master/Docs/Images/cat.jpg?raw=true)

### Let's create an abstraction

```csharp
interface IBox { T Content { get; } }

interface ICat { State State { get; } }

enum State { Alive, Dead }
```

### Here is our implementation

```csharp
class CardboardBox : IBox
{
public CardboardBox(T content) => Content = content;

public T Content { get; }
}

class ShroedingersCat : ICat
{
// Represents the superposition of the states
private readonly Lazy _superposition;

public ShroedingersCat(Lazy superposition) => _superposition = superposition;

// Decoherence of the superposition at the time of observation via an irreversible process
public State State => _superposition.Value;

public override string ToString() => $"{State} cat";
}
```

_It is important to note that our abstraction and our implementation do not know anything about any IoC containers at all._

### Let's glue all together

Just add the package reference to [IoC.Container](https://www.nuget.org/packages/IoC.Container). It ships entirely as NuGet packages.

_Using NuGet packages allows you to optimize your application to include only the necessary dependencies._

- Package Manager

```
Install-Package IoC.Container
```

- .NET CLI

```
dotnet add package IoC.Container
```

Declare 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.

Below 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_).

```csharp
public class Glue : IConfiguration
{
public IEnumerable Apply(IMutableContainer container)
{
// Returns single token for 2 bindings
yield return container
// Represents a cardboard box with any content
.Bind>().To>()
// Represents schrodinger's cat
.Bind().To();

// Models a random subatomic event that may or may not occur
var indeterminacy = new Random();

// Represents a quantum superposition of 2 states: Alive or Dead
yield return container.Bind().To(ctx => (State)indeterminacy.Next(2));
}
}
```

_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._

### Time to open boxes!

```csharp
// Creates the Inversion of Control container
using var container = Container.Create().Using();

// Composition Root
// Gets the cardboard box in the same way as the following expression:
// var box = new CardboardBox(new ShroedingersCat(new Lazy(() => (State)indeterminacy.Next(2))));
var box = container.Resolve>();

// Checks the cat's state
WriteLine(box.Content);
```

This 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:

```csharp
var indeterminacy = new Random();
var box = new CardboardBox(new ShroedingersCat(new Lazy(() => (State)indeterminacy.Next(2))));
```

It 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.

## NuGet packages

| | binary packages | source code packages ¹ |
| --- | --- | ---|
| 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) |
| 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) |
| 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) |

¹ _source code packages_ require C# 7.0 or higher

## ASP.NET Core

- Package Manager

```
Install-Package IoC.AspNetCore
```

- .NET CLI

```
dotnet add package IoC.AspNetCore
```

For __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)

```csharp
public static void Main(string[] args)
{
using var container = Container
// Creates an Inversion of Control container
.Create()
.Using();

// Creates a host
using var host = Host
.CreateDefaultBuilder(args)
// Adds a service provider for the Inversion of Control container
.UseServiceProviderFactory(new ServiceProviderFactory(container))
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); })
.Build();

host.Run();
}
```

For more details please see [this sample](Samples/WebApplication3) or [this Blazor sample](Samples/BlazorServerApp).

For __Blazor WebAssembly__ create the _IoC container_ and use the service provider factory based on this container at [Main](Samples/BlazorWebAssemblyApp/Program.cs)

```csharp
public static async Task Main(string[] args)
{
using var container = Container
// Creates an Inversion of Control container
.Create()
.Using();

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add("app");

// Adds a service provider for the Inversion of Control container
builder.ConfigureContainer(new ServiceProviderFactory(container));

await builder.Build().RunAsync();
}
```

For more details please see [this sample](Samples/BlazorWebAssemblyApp).

For __ASP.NET Core 2__ create the _IoC container_ with feature _AspNetCoreFeature_ and configure it at [Startup](Samples/WebApplication2/Startup.cs)

```csharp
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddControllersAsServices();

return Container
// Creates an Inversion of Control container
.Create()
// using ASP .NET Feature
.Using(new AspNetCoreFeature(services))
// using Glue
.Using()
// Resolves IServiceProvider
.Resolve();
}
```

For more details please see [this sample](Samples/WebApplication2).

## Interception

- Package Manager

```
Install-Package IoC.Interception
```

- .NET CLI

```
dotnet add package IoC.Interception
```

Add _InterceptionFeature_ to intercept calls to _IService_ by your own _MyInterceptor_

```csharp
using var container = Container
// Using the feature InterceptionFeature
.Using()
.Bind().To()
// Intercepts any invocations to any instances resolved via IoC container
.Intercept(key => true, new MyInterceptor())

container.Resolve();

```

where _MyInterceptor_ looks like:

```csharp
class MyInterceptor : IInterceptor
{
// Intercepts invocations and appends some logic around
public void Intercept(IInvocation invocation)
{
...
invocation.Proceed();
...
}
}
```

For details please see [this sample](IoC.Tests/UsageScenarios/Interception.cs).

## Why this one framework?

### Graph of 27 transient instances

![Transient](http://tcavs2015.cloudapp.net/guestAuth/app/rest/builds/buildType:DevTeam_IoCContainer_CreateReports,pinned:true,status:SUCCESS/artifacts/content/IoC.Benchmark.Transient-report.jpg)

### Graph of 20 transient instances and 1 singleton instance

![Singleton](http://tcavs2015.cloudapp.net/guestAuth/app/rest/builds/buildType:DevTeam_IoCContainer_CreateReports,pinned:true,status:SUCCESS/artifacts/content/IoC.Benchmark.Singleton-report.jpg)

### Graph of 364 transient instances of unique type

![Complex](http://tcavs2015.cloudapp.net/guestAuth/app/rest/builds/buildType:DevTeam_IoCContainer_CreateReports,pinned:true,status:SUCCESS/artifacts/content/IoC.Benchmark.Complex-report.jpg)

### Graph of 22 transient instances, including 3 Func to create 4 instances each time

![Func](http://tcavs2015.cloudapp.net/guestAuth/app/rest/builds/buildType:DevTeam_IoCContainer_CreateReports,pinned:true,status:SUCCESS/artifacts/content/IoC.Benchmark.Func-report.jpg)

### Graph of 22 transient instances, including 3 arrays of 4 instances in each

![Array](http://tcavs2015.cloudapp.net/guestAuth/app/rest/builds/buildType:DevTeam_IoCContainer_CreateReports,pinned:true,status:SUCCESS/artifacts/content/IoC.Benchmark.Array-report.jpg)

### Graph of 22 transient instances, including 3 enumerable of 4 instances in each

![Enum](http://tcavs2015.cloudapp.net/guestAuth/app/rest/builds/buildType:DevTeam_IoCContainer_CreateReports,pinned:true,status:SUCCESS/artifacts/content/IoC.Benchmark.Enum-report.jpg)

- __new__ - _Method_ when the graph of objects was constructed by operators _new_ only
- __Mean__ - arithmetic mean of the root instances resolved per nanosecond
- __Error__ - half of 99.9% confidence interval
- __StdDev__ - standard deviation of all measurements
- __Median__ - value separating the higher half of all measurements (50th percentile)
- __1 ns__ - 1 Nanosecond (0.000000001 sec)

_[BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet) was used to measure and analyze these results._

### Supported Platforms

- .NET 4.0+
- [.NET Core](https://docs.microsoft.com/en-us/dotnet/core/) 1.0+
- [.NET Standard](https://docs.microsoft.com/en-us/dotnet/standard/net-standard) 1.0+
- [UWP](https://docs.microsoft.com/en-us/windows/uwp/index) 10+

### Easy Integration

- [ASP.NET Core](#aspnet-core)
- [Xamarin](https://github.com/DevTeam/IoCContainer/blob/master/Samples/XamarinXaml)
- [Windows Presentation Foundation](https://github.com/DevTeam/IoCContainer/blob/master/Samples/WpfApp)
- [.NET core Windows Presentation Foundation](https://github.com/DevTeam/IoCContainer/blob/master/Samples/WpfAppNetCore)
- [Universal Windows Platform](https://github.com/DevTeam/IoCContainer/blob/master/Samples/UwpApp)
- [Windows Communication Foundation](https://github.com/DevTeam/IoCContainer/blob/master/Samples/WcfServiceLibrary)
- [Entity Framework](https://github.com/DevTeam/IoCContainer/tree/master/Samples/EntityFrameworkCore)

## Usage Scenarios

- Basics
- [Composition Root](#composition-root-)
- [Autowiring](#autowiring-)
- [Bindings](#bindings-)
- [Constants](#constants-)
- [Factories](#factories-)
- [Generics](#generics-)
- [Tags](#tags-)
- [Wrapper](#wrapper-)
- [Aspect-oriented DI](#aspect-oriented-di-)
- [Configurations](#configurations-)
- [Resolve Unbound](#resolve-unbound-)
- [Several contracts](#several-contracts-)
- [Autowiring with initialization](#autowiring-with-initialization-)
- [Child container](#child-container-)
- [Expression binding](#expression-binding-)
- [Method injection](#method-injection-)
- [Setter or field injection](#setter-or-field-injection-)
- [Dependency tag](#dependency-tag-)
- [Manual wiring](#manual-wiring-)
- [Func dependency](#func-dependency-)
- [Value types](#value-types-)
- [Generic autowiring](#generic-autowiring-)
- [Injection of default parameters](#injection-of-default-parameters-)
- [Optional injection](#optional-injection-)
- [Resolve an instance using arguments](#resolve-an-instance-using-arguments-)
- [Auto Disposing](#auto-disposing-)
- Lifetimes
- [Container Singleton lifetime](#container-singleton-lifetime-)
- [Disposing lifetime](#disposing-lifetime-)
- [Scope Root lifetime](#scope-root-lifetime-)
- [Singleton lifetime](#singleton-lifetime-)
- [Custom lifetime: thread Singleton](#custom-lifetime:-thread-singleton-)
- [Replacement of Lifetime](#replacement-of-lifetime-)
- BCL types
- [Arrays](#arrays-)
- [Collections](#collections-)
- [Enumerables](#enumerables-)
- [Funcs](#funcs-)
- [Lazy](#lazy-)
- [Nullable value type](#nullable-value-type-)
- [Observables](#observables-)
- [Sets](#sets-)
- [ThreadLocal](#threadlocal-)
- [Tuples](#tuples-)
- [Value Tuples](#value-tuples-)
- [Func with arguments](#func-with-arguments-)
- Async
- [ValueTask](#valuetask-)
- [Async Enumerables](#async-enumerables-)
- [Asynchronous construction](#asynchronous-construction-)
- [Cancellation of asynchronous construction](#cancellation-of-asynchronous-construction-)
- [Override the default task scheduler](#override-the-default-task-scheduler-)
- Advanced
- [Change configuration on-the-fly](#change-configuration-on-the-fly-)
- [Resolve Unbound for abstractions](#resolve-unbound-for-abstractions-)
- [Constructor choice](#constructor-choice-)
- [Container injection](#container-injection-)
- [Check a binding](#check-a-binding-)
- [Check for possible resolving](#check-for-possible-resolving-)
- [Tracing](#tracing-)
- [Custom autowiring strategy](#custom-autowiring-strategy-)
- [Custom builder](#custom-builder-)
- [Custom child container](#custom-child-container-)
- [Interception](#interception-)
- Samples
- [Cyclic dependency](#cyclic-dependency-)
- [Plugins](#plugins-)
- [Generator sample](#generator-sample-)
- [Wrapper sample](#wrapper-sample-)
- [Instant Messenger sample](#instant-messenger-sample-)

### 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)

``` CSharp
public void Run()
{
// Host runs a program
Program.TestMain();
}

class Program
{
// The application's entry point
public static void TestMain()
{
using var container =
Container.Create()
.Using();

// The Composition Root is a single location for objects construction
// it should be as close as possible to the application's entry point
var root = container.Resolve();

// Runs a logic
root.Run();
}

// Injects dependencies via a constructor
internal Program(IService service)
{
// Saves dependencies as internal fields
}

private void Run()
{
// Implements a logic using dependencies
}
}

// Represents the IoC container configuration
class Configuration: IConfiguration
{
public IEnumerable Apply(IMutableContainer container)
{
yield return container
.Bind().To()
.Bind().To();
}
}
```

### Autowiring [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Autowiring.cs)

Autowring 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.

``` CSharp
// Create the container and configure it, using full autowiring
using var container = Container
.Create()
.Bind().To()
.Bind().To()
.Container;

// Resolve an instance of interface `IService`
var instance = container.Resolve();
```

### Bindings [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Bindings.cs)

It is possible to bind any number of types.

``` CSharp
using var container = Container
.Create()
.Bind().To()
// Bind using few types
.Bind().Bind().Tag("abc").To()
.Container;

// Resolve instances using different types
var instance1 = container.Resolve("abc".AsTag());
var instance2 = container.Resolve("abc".AsTag());
```

### Constants [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Constants.cs)

It's obvious here.

``` CSharp
using var container = Container
.Create()
.Bind().To(ctx => 10)
.Container;
// Resolve an integer
var val = container.Resolve();
// Check the value
val.ShouldBe(10);
```

### Factories [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Factories.cs)

Use _Func<..., T>_ with arguments as a factory passing a state.

``` CSharp
using var container = Container
.Create()
.Bind().To()
.Bind().To()
.Container;

// Resolve a factory
var factory = container.Resolve>();

// Run factory passing the string "beta" as argument
var instance = factory("alpha");

// Check that argument "beta" was used during constructing an instance
instance.Name.ShouldBe("alpha");
```

It 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.

### Generics [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Generics.cs)

Autowring of generic types via binding of open generic types or generic type markers are working the same way.

``` CSharp
using var container = Container
.Create()
.Bind().To()
// Bind open generic interface to open generic implementation
.Bind(typeof(IService<>)).To(typeof(Service<>))
// Or (it is working the same) just bind generic interface to generic implementation, using marker classes TT, TT1, TT2 and so on
.Bind>().Tag("just generic").To>()
.Container;

// Resolve a generic instance using "open generic" binding
var instance1 = container.Resolve>();

// Resolve a generic instance using "just generic" binding
var instance2 = container.Resolve>("just generic".AsTag());
```

### Wrapper [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/SimpleWrapper.cs)

``` CSharp
public void Run()
{
// Create and configure a parent container
using var parentContainer = Container
.Create()
// Binds a service to wrap
.Bind().To()
.Container;

// Create and configure a child container
using var childContainer = parentContainer
.Create()
// Binds a wrapper, injecting the base IService from the parent container via constructor
.Bind().To()
.Container;

var service = childContainer.Resolve();

service.Value.ShouldBe("Wrapper abc");
}

public interface IService
{
string Value { get; }
}

public class Service: IService
{
public string Value => "abc";
}

public class WrapperForService : IService
{
private readonly IService _wrapping;

public WrapperForService(IService wrapping) => _wrapping = wrapping;

public string Value => $"Wrapper {_wrapping.Value}";
}
```

### Tags [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Tags.cs)

Tags are useful while binding to several implementations of the same abstract types.

``` CSharp
using var container = Container
.Create()
.Bind().To()
// Bind using several tags
.Bind().Tag(10).Tag().Tag("abc").To()
.Container;

// Resolve instances using tags
var instance1 = container.Resolve("abc".AsTag());
var instance2 = container.Resolve(10.AsTag());

// Resolve the instance using the empty tag
var instance3 = container.Resolve();
```

### 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)

This 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.

``` CSharp
public void Run()
{
var console = new Mock();

// Creates an aspect - oriented auto wiring strategy specifying
// which attributes should be used and which properties should be used to configure DI
var autowiringStrategy = AutowiringStrategies.AspectOriented()
.Type(attribute => attribute.Type)
.Order(attribute => attribute.Order)
.Tag(attribute => attribute.Tag);

using var container = Container
.Create()
// Configure the container to use DI aspects
.Bind().To(ctx => autowiringStrategy)
.Bind().Tag("MyConsole").To(ctx => console.Object)
.Bind().Tag("Prefix").To(ctx => "info")
.Bind().To()
.Container;

// Create a logger
var logger = container.Resolve();

// Log the message
logger.Log("Hello");

// Check the output has the appropriate format
console.Verify(i => i.WriteLine(It.IsRegex(".+ - info: Hello")));
}

// Represents the dependency aspect attribute to specify a type for injection.
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
public class TypeAttribute : Attribute
{
// A type, which will be used during an injection
public readonly Type Type;

public TypeAttribute(Type type) => Type = type;
}

// Represents the dependency aspect attribute to specify a tag for injection.
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
public class TagAttribute : Attribute
{
// A tag, which will be used during an injection
public readonly object Tag;

public TagAttribute(object tag) => Tag = tag;
}

// Represents the dependency aspect attribute to specify an order for injection.
[AttributeUsage(AttributeTargets.Method)]
public class OrderAttribute : Attribute
{
// An order to be used to invoke a method
public readonly int Order;

public OrderAttribute(int order) => Order = order;
}

public interface IConsole { void WriteLine(string text); }

public interface IClock { DateTimeOffset Now { get; } }

public interface ILogger { void Log(string message); }

public class Logger : ILogger
{
private readonly IConsole _console;
private IClock _clock;

// Constructor injection using the tag "MyConsole"
public Logger([Tag("MyConsole")] IConsole console) => _console = console;

// Method injection after constructor using specified type _Clock_
[Order(1)] public void Initialize([Type(typeof(Clock))] IClock clock) => _clock = clock;

// Setter injection after the method injection above using the tag "Prefix"
public string Prefix { get; [Tag("Prefix"), Order(2)] set; }

// Adds current time and prefix before a message and writes it to console
public void Log(string message) => _console?.WriteLine($"{_clock.Now} - {Prefix}: {message}");
}

public class Clock : IClock
{
// "clockName" dependency is not resolved here but has default value
public Clock([Type(typeof(string)), Tag("ClockName")] string clockName = "SPb") { }

public DateTimeOffset Now => DateTimeOffset.Now;
}
```

You can also specify your own aspect-oriented auto wiring by implementing the interface [_IAutowiringStrategy_](IoCContainer/blob/master/IoC/IAutowiringStrategy.cs).

### Configurations [![CSharp](https://img.shields.io/badge/C%23-code-blue.svg)](https://raw.githubusercontent.com/DevTeam/IoCContainer/master/IoC.Tests/UsageScenarios/Configurations.cs)

Configurations are used to dedicate a logic responsible for configuring containers.

``` CSharp
public void Run()
{
using var container = Container
.Create()
.Using();

var instance = container.Resolve();
}

public class Glue : IConfiguration
{
public IEnumerable Apply(IMutableContainer container)
{
yield return container
.Bind().To()
.Bind().To();
}
}
```

### 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)

By default, all instances of non-abstract or value types are ready to resolve and inject as dependencies.

``` CSharp
public void Run()
{
using var container = Container
.Create()
.Bind().To()
.Container;

// Resolve an instance of unregistered type
var instance = container.Resolve>(99);
instance.OtherService.Value.ShouldBe(99);
instance.OtherService.Count.ShouldBe(10);
}

class Service
{
public Service(OtherService otherService, IDependency dependency)
{
OtherService = otherService;
}

public OtherService OtherService { get; }
}

class OtherService
{
public OtherService(T value, int count = 10)
{
Value = value;
Count = count;
}

public T Value { get; }

public long Count { get; }
}
```

In 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.

### 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)

It is possible to bind several types to a single implementation.

``` CSharp
using var container = Container
.Create()
.Bind().To()
.Bind().To()
.Container;

// Resolve instances
var instance1 = container.Resolve();
var instance2 = container.Resolve();
```

### 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)

Sometimes 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.

``` CSharp
// Create a container and configure it using full autowiring
using var container = Container
.Create()
.Bind().To()
.Bind().To(
// Configure the container to invoke method "Initialize" for every created instance of this type
ctx => ctx.It.Initialize("Initialized!", ctx.Container.Resolve()))
.Container;

// Resolve an instance of interface `IService`
var instance = container.Resolve();

// Check the instance
instance.ShouldBeOfType();

// Check that the initialization has took place
instance.Name.ShouldBe("Initialized!");
```

:warning: It is not recommended because it is a cause of hidden dependencies.

### 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)

Child 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.

``` CSharp
using var parentContainer = Container
.Create()
.Bind().To()
// Bind IService to Service
.Bind().To()
.Container;

using var childContainer = parentContainer
.Create()
// Override binding of IService to Service
.Bind().To>()
.Container;

var instance1 = parentContainer.Resolve();
var instance2 = childContainer.Resolve();

childContainer.Parent.ShouldBe(parentContainer);
instance1.ShouldBeOfType();
instance2.ShouldBeOfType>();
```

### 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)

A 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_.

``` CSharp
using var container = Container
.Create()
.Bind().To(ctx => new Service(new Dependency()))
.Container;

// Resolve an instance
var instance = container.Resolve();
```

### 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)

:warning: Please use the constructor injection instead. The method injection is not recommended because it is a cause of hidden dependencies.

``` CSharp
// Create and configure a container using full autowiring
using var container = Container
.Create()
.Bind().To()
// Bind 'INamedService' to the instance creation and initialization, actually represented as an expression tree
.Bind().To(
// Select the constructor and inject a dependency into it
ctx => new InitializingNamedService(ctx.Container.Inject()),
// Configure the initializing method to invoke after the instance creation and inject the dependencies
// The first one is the value from context arguments at index 0
// The second one - is just dependency injection of type IDependency
ctx => ctx.It.Initialize((string) ctx.Args[0], ctx.Container.Inject()))
.Container;

// Resolve the instance using the argument "alpha"
var instance = container.Resolve("alpha");

// Check the instance type
instance.ShouldBeOfType();

// Check the injected dependency
instance.Name.ShouldBe("alpha");

// Resolve a function to create an instance
var func = container.Resolve>();

// Create an instance with the argument "beta"
var otherInstance = func("beta");

// Check the injected dependency
otherInstance.Name.ShouldBe("beta");
```

It is possible to use DI aspects (Attributes) to use full autowring instead.

### 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)

:warning: Please try using the constructor injection instead. The setter/field injection is not recommended because of it is a cause of hidden dependencies.

``` CSharp
using var container = Container
.Create()
.Bind().To()
// Bind 'INamedService' to the instance creation and initialization, actually represented as an expression tree
.Bind().To(
// Select a constructor and inject the dependency
ctx => new InitializingNamedService(ctx.Container.Inject()),
// Select a setter/field to inject after the instance creation and inject the value from arguments at index 0
ctx => ctx.Container.Assign(ctx.It.Name, (string)ctx.Args[0]))
.Container;

// Resolve the instance using the argument "alpha"
var instance = container.Resolve("alpha");

// Check the instance type
instance.ShouldBeOfType();

// Check the injected dependency
instance.Name.ShouldBe("alpha");

// Resolve a function to create an instance
var func = container.Resolve>();

// Create an instance with the argument "beta"
var otherInstance = func("beta");

// Check the injected dependency
otherInstance.Name.ShouldBe("beta");
```

It is possible to use DI aspects (Attributes) to use full autowring instead.

### 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)

Use a _tag_ to bind few dependencies for the same types.

``` CSharp
using var container = Container
.Create()
.Bind().Tag("MyDep").To()
// Configure autowiring and inject dependency tagged by "MyDep"
.Bind().To(ctx => new Service(ctx.Container.Inject("MyDep")))
.Container;

// Resolve an instance
var instance = container.Resolve();
```

### 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)

In 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.

``` CSharp
// Create and configure a container using manual wiring
using var container = Container
.Create()
.Bind().To()
// Bind 'INamedService' to the instance creation and initialization, actually represented as an expression tree
.Bind().To(
// Select the constructor and inject a dependency into it
ctx => new InitializingNamedService(ctx.Container.Inject()),
// Configure the initializing method to invoke for every created instance with all appropriate dependencies
// We used _Resolve_ instead _Inject_ just for example
ctx => ctx.It.Initialize("some name", ctx.Container.Resolve()))
.Container;

// Resolve an instance
var instance = container.Resolve();

// Check the instance
instance.ShouldBeOfType();

// Check the injected dependency
instance.Name.ShouldBe("some name");
```

It'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()`. 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()`. 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()`.**

### 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)

No comments. Everything is very simple!

``` CSharp
Func func = () => new Service(new Dependency());

using var container = Container
.Create()
.Bind().To(ctx => func())
.Container;

var instance = container.Resolve();
```

### 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)

Value types are fully supported avoiding any boxing/unboxing or cast operations, so the performance does not suffer!

``` CSharp
public void Run()
{
using var container = Container
.Create()
.Bind().To()
// Register the tracing builder
.Bind().As(Singleton).To()
// Register a struct
.Bind().To()
.Container;

// Resolve an instance
var instance = container.Resolve();

// Check the expression which was used to create an instances of MyStruct
var expressions = container.Resolve().Expressions;
var structExpression = expressions[new Key(typeof(MyStruct))].ToString();
// The actual code is "new MyStruct(new Dependency())"!
structExpression.ShouldBe("new MyStruct(new Dependency())");
// Obvious there are no any superfluous operations like a `boxing`, `unboxing` or `cast`,
// just only what is really necessary to create an instance
}

public struct MyStruct
{
public MyStruct(IDependency dependency) { }
}

// This builder saves expressions that used to create resolvers
public class TracingBuilder : IBuilder
{
public readonly IDictionary Expressions = new Dictionary();

public Expression Build(IBuildContext context, Expression expression)
{
Expressions[context.Key] = expression;
return expression;
}
}
```

### 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)

``` CSharp
public void Run()
{
using var container = Container.Create()
.Bind().To()
.Bind().To()
.Container;

// Resolve an instance
var instance = container.Resolve();

// Check the optional dependency
instance.State.ShouldBe("empty");
}

public class SomeService: IService
{
// "state" dependency is not resolved here but it has the default value "empty"
public SomeService(IDependency dependency, string state = "empty")
{
Dependency = dependency;
State = state;
}

public IDependency Dependency { get; }

public string State { get; }
}
```

### 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)

Autowiring 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<>, TTDictionary<> ... or create your own generic parameters markers or bind open generic types.

``` CSharp
public void Run()
{
// Create and configure the container using autowiring
using var container = Container
.Create()
.Bind().To()
// Bind using the predefined generic parameters marker TT (or TT1, TT2, TT3 ...)
.Bind>().To>()
// Bind using the predefined generic parameters marker TTList (or TTList1, TTList2 ...)
// For other cases there are TTComparable, TTComparable, TTEquatable, TTEnumerable, TTDictionary and etc.
.Bind>>().To>>()
// Bind using the custom generic parameters marker TCustom
.Bind>().Tag("custom marker").To>()
// Bind using the open generic type
.Bind(typeof(IService<>)).Tag("open type").To(typeof(Service<>))
.Container;

// Resolve a generic instance
var listService = container.Resolve>>();
var instances = container.Resolve>>();

instances.Count.ShouldBe(3);
// Check the instance's type
foreach (var instance in instances)
{
instance.ShouldBeOfType>();
}

listService.ShouldBeOfType>>();
}

// Custom generic type marker using predefined attribute `GenericTypeArgument`
[GenericTypeArgument]
class TTMy { }
```

### 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)

``` CSharp
public void Run()
{
using var container = Container.Create()
.Bind().To()
.Bind().To(ctx =>
new SomeService(
ctx.Container.Inject(),
// Injects default(string) if the dependency cannot be resolved
ctx.Container.TryInject(),
// Injects default(int) if the dependency cannot be resolved
ctx.Container.TryInject(),
// Injects int? if the dependency cannot be resolved
ctx.Container.TryInjectValue()))
.Container;

// Resolve an instance
var instance = container.Resolve();

// Check optional dependencies
instance.State.ShouldBe("empty,True,False");
}

public class SomeService: IService
{
public SomeService(IDependency dependency, string state, int? val1, int? val2)
{
Dependency = dependency;
State = state ?? $"empty,{val1.HasValue},{val2.HasValue}";
}

public IDependency Dependency { get; }

public string State { get; }
}
```

### 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)

``` CSharp
using var container = Container
.Create()
.Bind().To()
// Bind 'INamedService' to the instance creation and initialization, actually represented as an expression tree
.Bind().To(
// Select the constructor and inject the value from arguments at index 0
ctx => new NamedService(ctx.Container.Inject(), (string) ctx.Args[0]))
.Container;

// Resolve the instance using the argument "alpha"
var instance = container.Resolve("alpha");

// Check the instance type
instance.ShouldBeOfType();

// Check the injected dependency
instance.Name.ShouldBe("alpha");

// Resolve a function to create an instance
var func = container.Resolve>();

// Create an instance with the argument "beta"
var otherInstance = func("beta");

// Check the injected dependency
otherInstance.Name.ShouldBe("beta");
```

### 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)

A [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.

``` CSharp
var disposableService = new Mock();

using (
var container = Container
.Create()
.Bind().As(Lifetime.Singleton).To(ctx => disposableService.Object)
.Container)
{
var disposableInstance = container.Resolve();
}

// Check the singleton was disposed after the container was disposed
disposableService.Verify(i => i.Dispose(), Times.Once);
disposableService.Verify(i => i.DisposeAsync(), Times.Once);
```

### 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)

Each container may have its own [singleton](https://en.wikipedia.org/wiki/Singleton_pattern) instance for specific binding.

``` CSharp
var container = Container
.Create()
.Bind().To()
// Use the Container Singleton lifetime
.Bind().As(ContainerSingleton).To()
.Container;

// Resolve the container singleton twice
var instance1 = container.Resolve();
var instance2 = container.Resolve();

// Check that instances from the parent container are equal
instance1.ShouldBe(instance2);

// Create a child container
var childContainer = container.Create();

// Resolve the container singleton twice
var childInstance1 = childContainer.Resolve();
var childInstance2 = childContainer.Resolve();

// Check that instances from the child container are equal
childInstance1.ShouldBe(childInstance2);

// Check that instances from different containers are not equal
instance1.ShouldNotBe(childInstance1);

// Dispose instances on disposing a child container
childContainer.Dispose();
((Service)childInstance1).DisposeCount.ShouldBe(1);
((Service)childInstance2).DisposeCount.ShouldBe(1);
((Service)instance1).DisposeCount.ShouldBe(0);
((Service)instance2).DisposeCount.ShouldBe(0);

// Dispose instances on disposing a container
container.Dispose();
((Service)childInstance1).DisposeCount.ShouldBe(1);
((Service)childInstance2).DisposeCount.ShouldBe(1);
((Service)instance1).DisposeCount.ShouldBe(1);
((Service)instance2).DisposeCount.ShouldBe(1);
```

### 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)

``` CSharp
var container = Container
.Create()
.Bind().To()
// Use the Disposing lifetime
.Bind().As(Disposing).To()
.Container;

var instance = container.Resolve();

// Dispose instances on disposing a container
container.Dispose();
((Service)instance).DisposeCount.ShouldBe(1);
```

### 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)

ScopeRoot lifetime creates an instance together with new scope and allows control of all scope singletons by IScopeToken.

``` CSharp
using var container = Container
.Create()
// Bind "session" as a root of scope
.Bind().As(ScopeRoot).To()
// Bind a dependency as a container singleton
.Bind().As(ContainerSingleton).To()
// It is optional. Bind IDisposable to IScopeToken to prevent any reference to IoC types from models
.Bind().To(ctx => ctx.Container.Inject())
.Container;

// Resolve 2 sessions in own scopes
var session1 = container.Resolve();
var session2 = container.Resolve();

// Check sessions are not equal
session1.ShouldNotBe(session2);

// Check singletons are equal in the first scope
session1.Service1.ShouldBe(session1.Service2);

// Check singletons are equal in the second scope
session2.Service1.ShouldBe(session2.Service2);

// Check singletons are not equal for different scopes
session1.Service1.ShouldNotBe(session2.Service1);

// Dispose of the instance from the first scope
session1.Dispose();

// Check dependencies are disposed for the first scope
session1.Service1.DisposeCounter.ShouldBe(1);

// Dispose container
container.Dispose();

// Check all dependencies are disposed for the all scopes
session2.Service1.DisposeCounter.ShouldBe(1);
session1.Service1.DisposeCounter.ShouldBe(1);
class Service: IDisposable
{
public int DisposeCounter;

public void Dispose() => DisposeCounter++;
}

class Session: IDisposable
{
private readonly IDisposable _scope;
public readonly Service Service1;
public readonly Service Service2;

public Session(
// There is no reference to the IoC type here
IDisposable scope,
Service service1,
Service service2)
{
_scope = scope;
Service1 = service1;
Service2 = service2;
}

public void Dispose() => _scope.Dispose();
}
```

### 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)

[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.

``` CSharp
var container = Container
.Create()
.Bind().To()
// Use the Singleton lifetime
.Bind().As(Singleton).To()
.Container;

// Resolve the singleton twice
var instance1 = container.Resolve();
var instance2 = container.Resolve();

// Check that instances from the parent container are equal
instance1.ShouldBe(instance2);

// Create a child container
using var childContainer = container.Create();

// Resolve the singleton twice
var childInstance1 = childContainer.Resolve();
var childInstance2 = childContainer.Resolve();

// Check that instances from the child container are equal
childInstance1.ShouldBe(childInstance2);

// Check that instances from different containers are equal
instance1.ShouldBe(childInstance1);

// Dispose of instances on disposing of a container
container.Dispose();
((Service)childInstance1).DisposeCount.ShouldBe(1);
((Service)childInstance2).DisposeCount.ShouldBe(1);
((Service)instance1).DisposeCount.ShouldBe(1);
((Service)instance2).DisposeCount.ShouldBe(1);
```

The lifetime could be:
- _Transient_ - a new instance is creating each time (it's default lifetime)
- [_Singleton_](https://en.wikipedia.org/wiki/Singleton_pattern) - single instance
- _ContainerSingleton_ - singleton per container
- _ScopeSingleton_ - singleton per scope
- _ScopeRoot_ - root of a scope
- _Disposing_ - Automatically calls a Disposable() method for disposable instances

### 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)

It 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.

``` CSharp
public void Run()
{
var counter = new Mock();

using var container = Container
.Create()
.Bind().To(ctx => counter.Object)
// Replace the Singleton lifetime with a custom lifetime
.Bind().Tag(Lifetime.Singleton).To(
// Select the constructor
ctx => new MySingletonLifetime(
// Inject the singleton lifetime from the parent container for partially delegating logic
ctx.Container.Parent.Inject(Lifetime.Singleton),
// Inject a counter to store the number of created instances
ctx.Container.Inject()))
// Configure the container as usual
.Bind().To()
// Bind using the custom implementation of Singleton lifetime
.Bind().As(Lifetime.Singleton).To()
.Container;

// Resolve the singleton twice using the custom lifetime
var instance1 = container.Resolve();
var instance2 = container.Resolve();

// Check that instances are equal
instance1.ShouldBe(instance2);

// Check the number of created instances
counter.Verify(i => i.Increment(), Times.Exactly(2));
}

// Represents the instance counter
public interface ICounter
{
void Increment();
}

public class MySingletonLifetime : ILifetime
{
// Stores 'IncrementCounter' method info to the static field
private static readonly MethodInfo IncrementCounterMethodInfo = typeof(MySingletonLifetime).GetTypeInfo().DeclaredMethods.Single(i => i.Name == nameof(IncrementCounter));

private readonly ILifetime _baseSingletonLifetime;
private readonly ICounter _counter;

// Stores the base lifetime and the instance counter
public MySingletonLifetime(ILifetime baseSingletonLifetime, ICounter counter)
{
_baseSingletonLifetime = baseSingletonLifetime;
_counter = counter;
}

public Expression Build(IBuildContext context, Expression expression)
{
// Builds expression using base lifetime
expression = _baseSingletonLifetime.Build(context, expression);

// Defines `this` variable to store the reference to the current lifetime instance to call internal method 'IncrementCounter'
var thisVar = Expression.Constant(this);

// Creates a code block
return Expression.Block(
// Adds the expression to call the method 'IncrementCounter' for the current lifetime instance
Expression.Call(thisVar, IncrementCounterMethodInfo),
// Returns the expression to create an instance
expression);
}

// Creates a similar lifetime to use with generic instances
public ILifetime CreateLifetime() => new MySingletonLifetime(_baseSingletonLifetime.CreateLifetime(), _counter);

// Select a container to resolve dependencies using the Singleton lifetime logic
public IContainer SelectContainer(IContainer registrationContainer, IContainer resolvingContainer) =>
_baseSingletonLifetime.SelectContainer(registrationContainer, resolvingContainer);

// Disposes the instance of the Singleton lifetime
public void Dispose() => _baseSingletonLifetime.Dispose();

// Just counts the number of requested instances
internal void IncrementCounter() => _counter.Increment();
}
```

### 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)

Sometimes 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<>_](IoC/Lifetimes/KeyBasedLifetime.cs).

``` CSharp
public void Run()
{
var finish = new ManualResetEvent(false);

var container = Container
.Create()
.Bind().To()
// Bind an interface to an implementation using the singleton per a thread lifetime
.Bind().Lifetime(new ThreadLifetime()).To()
.Container;

// Resolve the singleton twice
var instance1 = container.Resolve