Skip to content

An ultra light-weight dependency injection container built around the power of factories ported to C++!

License

Notifications You must be signed in to change notification settings

FurryBuilder/FactorItpp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

76 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FactorIt++ teamcity build status

This is a port of the FactorIt .NET dependency injection container to C++. This port is designed to behave and feel just like the original. It uses the same fluent interface as the .NET version and strive to offer a similar feature set.

Take a look at the FactorIt repository to get a better idea of where this is going.

Feature Compatibility List

Feature .NET C++
No magic
Fluent interface
Read-only interface
Write-only interface
Templated/Generic binding
Templated/Generic unbinding
Templated/Generic resolving
Service keys
Decorators
Notifications
Child containers
Resolving scope
Auto cleanup 1
  1. Partially supported. Service destructor will be called when shared_ptr dies.

Basic Scenarios

Configuration

To create a root container, simply use the CreateRoot() static method. This ensures that root containers are clearly identified in your code.

auto container = Container::CreateRoot();

Then, you can simply bind any interface to a factory using the Bind/To fluent syntax provided by the container.

container
    ->Bind<IService>()
    ->To([](IServiceLocator* l) {
        return std::make_shared<ConcreteService>();
    });

Since this is a little long to write, we also provide you with a really simple shortcuts for services that have a default constructor.

container
    ->Bind<IService>()
    ->To<ConcreteService>();

If you need to pass the container around, you can either use the IBindingRoot interface for a write only container or the IServiceLocator interface for a read only container.

Usage

To extract a dependency from the container, you can simply use the Resolve method. On the first call, this will create an instance of the bound type using the provided factory. Subsequent calls will resolve to the same instance. Resolving is a thread safe operation.

auto aConcreteService = container
    ->Resolve<IService>();

If the service might not yet be registered in the container, you can use the ResolveOrDefault method that will ensure that a customizable default value is returned.

auto aConcreteService = container
    ->ResolveOrDefault<IService>([]() {
        return std::shared_ptr<IService>(nullptr);
    });

Advanced Scenarios

Keys

As the amount of services in the container grows, you might see the need to register the same interface multiple times but with different factories. For instance, when using Reactive Extensions, you might want to register the scheduler_interface interface for each type of schedulers your application requires. The Bind method enables you to provide an optional key parameter for those cases.

container
    ->Bind<scheduler_interface>("background")
    ->To<new_thread>();
container
    ->Bind<scheduler_interface>("immediate")
    ->To<immediate>();

You can also provide a default instance, when no key is provided, or an alias by using the service locator provided as the first parameter of the factory.

container
    ->Bind<scheduler_interface>()
    ->To([](IServiceLocator* l) {
        return l->Resolve<scheduler_interface>("background")
    });

Unbinding

In some rare cases, you will want to remove a specific service from the container. For this, you can use the Unbind method.

container
    ->Unbind<scheduler_interface>("background");

Notifications

Sometimes, you will also need to schedule operations to be executed when a specific contract is registered. This could be useful if you insert plugins dynamically into the container or if you simply need to notify your log manager that a new logging destination has been registered. This can be done using the Postpone method.

container
    ->Postpone<ILogDestination>([](std::shared_ptr<ILogDestination> dest) {
        LogManager.Add(dest);
    });

About

An ultra light-weight dependency injection container built around the power of factories ported to C++!

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages