Skip to main content

Glossary

The following terms and definitions are used in this documentation.

Service type | Implementation type

The Service type is usually an interface or an abstract class type used for service resolution or dependency injection. The Implementation type is the actual type registered to the Service type. A registration maps the Service type to an Implementation type. The Implementation type must implement or extend the Service type.

Example where a Service type is mapped to an Implementation type:

container.Register<IService, Implementation>();

The Service type used for requesting a service from the container:

container.Resolve<IService>(); // returns Implementation

Service registration | Registered service

It's an entity created by Stashbox when a service is registered. The service registration stores required information about how to instantiate the service, e.g., reflected type information, name, lifetime, conditions, and more.

In this example, we are registering a named service. The container will create a service registration entity to store the type mapping and the name. During resolution, the container will find the registration by checking for the Service type and the name.

// the registration entity will look like: 
// IService => Implementation, name: Example
container.Register<IService, Implementation>("Example");
var service = container.Resolve<IService>("Example");

Injectable dependency

It's a constructor/method argument or a property/field of a registered Implementation type that gets evaluated (injected) by Stashbox during the service's construction.

In this example, Implementation has an IDependency injectable dependency in its constructor.

class Implementation : IService
{
public Implementation(IDependency dependency)
{ }
}

Resolution tree

It's the structural representation of a service's resolution process. It describes the instantiation order of the dependencies required to resolve the desired type.

Let's see through an example:

class A
{
public A(B b, C c) { }
}

class B
{
public B(C c, D d) { }
}

class C { }
class D { }

When we request the service A, the container constructs the following resolution tree based on the dependencies and sub-dependencies.

        A
/ \
B C
/ \
C D

The container instantiates those services first that don't have any dependencies. C and D will be injected into B. Then, a new C is instantiated (if it's transient) and injected into A along with the previously created B.

Dependency resolver

It's the container itself or the current scope, depending on which was asked to resolve a particular service. They are both implementing Stashbox's IDependencyResolver and the .NET framework's IServiceProvider interface and can be used for service resolution.

info

Stashbox implicitly injects the current scope wherever IDependencyResolver or IServiceProvider is requested.

Root scope

It's the main scope created inside every container instance. It stores and handles the lifetime of all singletons. It's the base of each subsequent scope created by the container with the .BeginScope() method.

caution

Scoped services requested from the container (and not from a scope) are managed by the root scope. This can lead to issues because their lifetime will effectively switch to singleton. Always be sure that you don't resolve scoped services directly from the container, only from a scope. This case is monitored by the lifetime validation rule when it's enabled.

Named resolution

It's a resolution request for a named service. The same applies, when the container sees a dependency in the resolution tree with a name (set by attributes or bindings); it will search for a matching Named registration to inject.

container.Register<IService, Implementation>("Example");
// the named request.
var service = container.Resolve<IService>("Example");

Self registration

It's a service registration that's mapped to itself. This means its service and implementation type is the same.

// equivalent to container.Register<Implementation, Implementation>();
container.Register<Implementation>();