Skip to content

Compile-time generated IoC container made possible using Roslyn Code Generators

Notifications You must be signed in to change notification settings

anotherlongname/Cogent.IoC

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WIP!!! - This project is very much a work in progress - WIP!!!

Cogent IoC

Compile-time generated IoC container made possible using Roslyn Code Generators

Progress

  • Parameterized Factory Registration
  • Validation of dependency graph
  • Correct error handling and code highlighting
  • Transient Registration
  • Singleton Registration
  • Delegate Registration
  • Work with Generic types correctly
  • Support for multi-constructor dependencies
  • Parameterless Factory Registration

Overview

TODO

Usage

To create a container class, first inherit the Container class. Then add your registrations as interfaces to it. Be sure to declare your class as partial so the generated code can be created correctly:

public partial class MyContainer : Container,
    Register.Transient<IMyService, MyImplimentation>,
    Register.Singleton<MySingletonService, MySingletonService>
{
}

The following registrations are supported:

Transient

Register a service that will be instantiated each time the service is injected.

Register.Transient<TService>
Register.Transient<TService, TImplimentation>

Singleton

Register a service that will be instantiated only on first time it is injected, and will be shared throughout the contianer

Register.Singleton<TService>
Register.Singleton<TService, TImplimentation>

Delegate

Register a delegate that will be used to create the specified service. The interface will require a method to be created on the nongenerated side that will return the specified service, given a set of dependencies

Register.Delegate<TService>
Register.Delegate<TService, TDependency>
Register.Delegate<TService, TDependency1, TDependency2>
Register.Delegate<TService, TDependency1, TDependency2, TDependency3>
Register.Delegate<TService, TDependency1, TDependency2, TDependency3, TDependency4>
Register.Delegate<TService, TDependency1, TDependency2, TDependency3, TDependency4, TDependency5>

The corresponding required method will look similar to this:

TService Register.Delegate<TService, TDependency>.Create(TDependency dependency)
{
    ...
}

Factory

Register an interface as a factory that can be used to resolve a service when required

Register.Factory<TFactory>

NOTE: Currently only parameterless service creation is possible within factories

ConstructorFor Attribute

You can add the ConstructorFor attribute on your container in order to have it generate a method to create a specified service type

[ConstructorFor(typeof(MyService))]
public partial class MyContianer : Container,
    Register.Transient<MyService>
{
}

Using a Generated Container

To use the container you can simply construct it and call any creat methods that you have included by adding ConstructorFor attributes, or by calling the Resolve or TryResolve methods.

var contianer = new MyContainer();
var myService = container.CreateMyService();
var myOtherService = container.Resolve<MyOtherService>(); // or Resolve(typeof(MyOtherService))

ASP.Net Core Support

Cogent IoC supports replacing the default ASP.Net Core service provider. This is technically not a full "replacement" of the service provider, but it easily integrates into the default provider and allows resolving dependencies from both Cogent IoC and the ASP.Net service provider.

Instead of using the Container type, use the AspNetCoreContainer type. This will add an IServiceProvider that can be used for delegate registrations to allow access to dependencies in the default Service Provider. Because the container is generated at compile-time you normally can't have direct access to the Service Provider services, but delegate registrations allow you to reference the Service Provider after it has been created.

public partial class MyContainer : AspNetCoreContainer,
    Register.Delegate<IConfiguration>
{
    IConfiguration Register.Delegate<IConfiguration>.Create()
        => (IConfiguration)ServiceProvider.GetService(typeof(IConfiguration));
}

This will also add a ServiceProviderFactory for the container to easily replace the Service Provider during startup. During the host builder call the .UseServiceProviderFactory() method and pass the generated factory method {ContainerName}.ServiceProviderFactory.Create()

// Program.cs

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                }).UseServiceProviderFactory(MyContainer.ServiceProviderFactory.Create());

About

Compile-time generated IoC container made possible using Roslyn Code Generators

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages