README
View on GitHub ↗AutoCtor
AutoCtor is a Roslyn Source Generator that will automatically create a constructor for your class for use with constructor Dependency Injection.
+[AutoConstruct]
public partial class AService
{
private readonly IDataContext _dataContext;
private readonly IDataService _dataService;
private readonly IExternalService _externalService;
private readonly ICacheService _cacheService;
private readonly ICacheProvider _cacheProvider;
private readonly IUserService _userService;
- public AService(
- IDataContext dataContext,
- IDataService dataService,
- IExternalService externalService,
- ICacheService cacheService,
- ICacheProvider cacheProvider,
- IUserService userService
- )
- {
- _dataContext = dataContext;
- _dataService = dataService;
- _externalService = externalService;
- _cacheService = cacheService;
- _cacheProvider = cacheProvider;
- _userService = userService;
- }
}
Contents
- NuGet packages
- Code Fixes (new in 3.0)
- Service Provider Source Generator (new in 4.0)
- Examples
- Post Constructor Initialization
- Argument Guards
- Keyed Services
- Service Provider
- Other
NuGet packages
https://nuget.org/packages/AutoCtor/
Code Fixes (new in 3.0)
Starting in version 3.0, a new diagnostic has been introduced: ACTR007 Use [AutoConstruct] instead of manual constructor. This will appear on constructors that can be automatically converted to use [AutoConstruct]. A code fix is also available to perform the conversion automatically.
In 3.1 another code fix was added: Add [AutoConstruct] to type. This will add [AutoConstruct] to a type with no constructor and relevant fields. This is useful when working on a new type.
Service Provider Source Generator (new in 4.0)
In version 4.0 you can now generate your own Service Provider that will work with the constructors generated by AutoCtor. See Service Provider
Examples
Basic
[AutoConstruct]
public partial class Basic
{
private readonly IService _service;
private readonly IList<string> _list = new List<string>();
}
What gets generated
//HintName: Basic.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/distantcam/AutoCtor
// </auto-generated>
//------------------------------------------------------------------------------
partial class Basic
{
[global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")]
public Basic(global::IService service)
{
this._service = service;
}
}
Inherited
public abstract class BaseClass
{
protected IAnotherService _anotherService;
public BaseClass(IAnotherService anotherService)
{
_anotherService = anotherService;
}
}
[AutoConstruct]
public partial class Inherited : BaseClass
{
private readonly IService _service;
}
What gets generated
//HintName: Inherited.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/distantcam/AutoCtor
// </auto-generated>
//------------------------------------------------------------------------------
partial class Inherited
{
[global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")]
public Inherited(
global::IAnotherService anotherService,
global::IService service
) : base(anotherService)
{
this._service = service;
}
}
Properties
// AutoCtor will initialize these
public string GetProperty { get; }
protected string ProtectedProperty { get; }
public string InitProperty { get; init; }
public required string RequiredProperty { get; set; }
// AutoCtor will ignore these
public string InitializerProperty { get; } = "Constant";
public string GetSetProperty { get; set; }
public string FixedProperty => "Constant";
public string RedirectedProperty => InitializerProperty;
What gets generated
//HintName: Properties.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/distantcam/AutoCtor
// </auto-generated>
//------------------------------------------------------------------------------
partial class Properties
{
[global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")]
public Properties(
string getProperty,
string protectedProperty,
string initProperty,
string requiredProperty
)
{
this.GetProperty = getProperty;
this.ProtectedProperty = protectedProperty;
this.InitProperty = initProperty;
this.RequiredProperty = requiredProperty;
}
}
Post Constructor Initialization
You can mark a method to be called at the end of the constructor with the attribute [AutoPostConstruct]. This method must return void.
[AutoConstruct]
public partial class PostConstruct
{
private readonly IService _service;
[AutoPostConstruct]
private void Initialize()
{
}
}
What gets generated
//HintName: PostConstruct.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/distantcam/AutoCtor
// </auto-generated>
//------------------------------------------------------------------------------
partial class PostConstruct
{
[global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")]
public PostConstruct(global::IService service)
{
this._service = service;
Initialize();
}
}
Extra Parameters
Post construct methods can also take parameters. The generated constructor will include these parameters.
[AutoConstruct]
public partial class PostConstructWithParameter
{
private readonly IService _service;
[AutoPostConstruct]
private void Initialize(IInitializeService initialiseService)
{
}
}
What gets generated
//HintName: PostConstructWithParameter.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/distantcam/AutoCtor
// </auto-generated>
//------------------------------------------------------------------------------
partial class PostConstructWithParameter
{
[global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")]
public PostConstructWithParameter(
global::IService service,
global::IInitializeService initialiseService
)
{
this._service = service;
Initialize(initialiseService);
}
}
out/ref Parameters
Parameters marked with out or ref are set back to any fields that match the same type. This can be used to set readonly fields with more complex logic.
[AutoConstruct]
public partial class PostConstructWithOutParameter
{
private readonly IService _service;
private readonly IOtherService _otherService;
[AutoPostConstruct]
private void Initialize(IServiceProvider services, out IService service)
{
service = services.GetService<IService>();
}
}
What gets generated
//HintName: PostConstructWithOutParameter.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/distantcam/AutoCtor
// </auto-generated>
//------------------------------------------------------------------------------
partial class PostConstructWithOutParameter
{
[global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")]
public PostConstructWithOutParameter(
global::IOtherService otherService,
global::IServiceProvider services
)
{
this._otherService = otherService;
Initialize(services, out this._service);
}
}
Optional Parameters
[AutoConstruct]
public partial class PostConstructWithDefaultParameter
{
[AutoPostConstruct]
private void Initialize(Service? service = default)
{
}
}
What gets generated
//HintName: PostConstructWithDefaultParameter.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/distantcam/AutoCtor
// </auto-generated>
//------------------------------------------------------------------------------
partial class PostConstructWithDefaultParameter
{
[global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")]
public PostConstructWithDefaultParameter(global::Service service = default)
{
Initialize(service);
}
}
Argument Guards
Null guards for the arguments to the constructor can be added in 2 ways.
In your project you can add a AutoCtorGuards property.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AutoCtorGuards>true</AutoCtorGuards>
</PropertyGroup>
</Project>
OR
In each AutoConstruct attribute you can add a setting to enable/disable guards.
[AutoConstruct(GuardSetting.Enabled)]
public partial class Guarded
{
private readonly IService _service;
}
What gets generated
//HintName: Guarded.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/distantcam/AutoCtor
// </auto-generated>
//------------------------------------------------------------------------------
partial class Guarded
{
[global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")]
public Guarded(global::IService service)
{
this._service = service ?? throw new global::System.ArgumentNullException("service");
}
}
Keyed Services
When using Microsoft.Extensions.DependencyInjection you can mark fields and properties with [AutoKeyedService] and it will be included in the constructor.
[AutoConstruct]
public partial class Keyed
{
[AutoKeyedService("key")]
private readonly IService _keyedService;
}
What gets generated
//HintName: Keyed.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/distantcam/AutoCtor
// </auto-generated>
//------------------------------------------------------------------------------
partial class Keyed
{
[global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")]
public Keyed(
[global::Microsoft.Extensions.DependencyInjection.FromKeyedServices("key")] global::IService keyedService
)
{
this._keyedService = keyedService;
}
}
Service Provider
[ServiceProvider]
[Singleton<IClock, Clock>]
[Singleton<IGreeter, Greeter>]
public sealed partial class Container;
[AutoConstruct]
public partial class Greeter : IGreeter
{
private readonly IClock _clock;
}
What gets generated
//HintName: Container.ServiceProvider.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/distantcam/AutoCtor
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
partial class Container :
global::System.IServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService,
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService,
global::System.IDisposable,
Container.IResolver<global::IClock>,
Container.IResolver<global::IGreeter>,
Container.IResolver<global::System.Collections.Generic.IEnumerable<global::IClock>>,
Container.IResolver<global::System.Collections.Generic.IEnumerable<global::IGreeter>>,
Container.IResolver<global::System.IServiceProvider>,
Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>,
Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>,
Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>,
Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>
{
private readonly object _lock = new object();
private global::System.Collections.Generic.List<object>? _disposables;
private volatile global::IClock? _S0;
private global::IClock S0()
{
var service = _S0;
if (service is not null)
return service;
lock (_lock)
return (_S0 ??= new global::Clock());
}
private volatile global::IGreeter? _S1;
private global::IGreeter S1()
{
var service = _S1;
if (service is not null)
return service;
lock (_lock)
return (_S1 ??= new global::Greeter(S0()));
}
private object? Resolve(global::System.Type type, object? key, bool probe)
{
if (key is null)
{
if (type == typeof(global::IClock))
return probe ? this : (object)(S0());
if (type == typeof(global::IGreeter))
return probe ? this : (object)(S1());
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IClock>))
return probe ? this : (object)(new global::IClock[] { S0() });
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IGreeter>))
return probe ? this : (object)(new global::IGreeter[] { S1() });
if (type == typeof(global::System.IServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService))
return probe ? this : (object)(this);
return null;
}
return null;
}
private global::System.IServiceProvider? Fallback => null;
public object? GetService(global::System.Type serviceType)
=> GetKeyedService(serviceType, null);
public object? GetKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, false)
?? (serviceKey == null ? Fallback?.GetService(serviceType) : (Fallback as global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider)?.GetKeyedService(serviceType, serviceKey));
public object GetRequiredKeyedService(global::System.Type serviceType, object? serviceKey)
=> GetKeyedService(serviceType, serviceKey)
?? throw new global::System.InvalidOperationException("No service for type '" + serviceType + "' has been registered.");
public T? GetService<T>()
=> this is Container.IResolver<T> resolver ? resolver.Get() : GetService(typeof(T)) is T service ? service : default;
public T GetRequiredService<T>()
=> this is Container.IResolver<T> resolver ? resolver.Get() : (T)GetRequiredKeyedService(typeof(T), null);
private interface IResolver<T> { T Get(); }
global::IClock Container.IResolver<global::IClock>.Get()
=> S0();
global::IGreeter Container.IResolver<global::IGreeter>.Get()
=> S1();
global::System.Collections.Generic.IEnumerable<global::IClock> Container.IResolver<global::System.Collections.Generic.IEnumerable<global::IClock>>.Get()
=> new global::IClock[] { S0() };
global::System.Collections.Generic.IEnumerable<global::IGreeter> Container.IResolver<global::System.Collections.Generic.IEnumerable<global::IGreeter>>.Get()
=> new global::IGreeter[] { S1() };
global::System.IServiceProvider Container.IResolver<global::System.IServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>.Get()
=> this;
public bool IsService(global::System.Type serviceType)
=> IsKeyedService(serviceType, null);
public bool IsKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, true) != null || (serviceKey == null ? (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)?.IsService(serviceType) == true : (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)?.IsKeyedService(serviceType, serviceKey) == true);
public Scope CreateScope() => new Scope(this);
global::Microsoft.Extensions.DependencyInjection.IServiceScope global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory.CreateScope() => CreateScope();
private static T Required<T>(object? service)
=> service is T t ? t : throw new global::System.InvalidOperationException("No service for type '" + typeof(T) + "' has been registered.");
private T Track<T>(T service)
{
if (service is global::System.IDisposable)
lock (_lock)
(_disposables ??= new global::System.Collections.Generic.List<object>()).Add(service);
return service;
}
private object[] Drain()
{
lock (_lock)
{
var items = _disposables?.ToArray() ?? new object[0];
_disposables = null;
global::System.Array.Reverse(items);
return items;
}
}
public void Dispose()
{
foreach (var item in Drain())
{
if (item is global::System.IDisposable disposable)
{
disposable.Dispose();
}
}
}
[global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")]
public sealed class Scope :
global::System.IServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService,
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService,
global::System.IDisposable,
global::Microsoft.Extensions.DependencyInjection.IServiceScope,
Container.IResolver<global::IClock>,
Container.IResolver<global::IGreeter>,
Container.IResolver<global::System.Collections.Generic.IEnumerable<global::IClock>>,
Container.IResolver<global::System.Collections.Generic.IEnumerable<global::IGreeter>>,
Container.IResolver<global::System.IServiceProvider>,
Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>,
Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>,
Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>,
Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>
{
private readonly object _lock = new object();
private global::System.Collections.Generic.List<object>? _disposables;
private readonly Container _root;
public Scope(Container root) => _root = root;
public global::System.IServiceProvider ServiceProvider => this;
private global::IClock S0() => _root.S0();
private global::IGreeter S1() => _root.S1();
private object? Resolve(global::System.Type type, object? key, bool probe)
{
if (key is null)
{
if (type == typeof(global::IClock))
return probe ? this : (object)(S0());
if (type == typeof(global::IGreeter))
return probe ? this : (object)(S1());
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IClock>))
return probe ? this : (object)(new global::IClock[] { S0() });
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IGreeter>))
return probe ? this : (object)(new global::IGreeter[] { S1() });
if (type == typeof(global::System.IServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService))
return probe ? this : (object)(this);
return null;
}
return null;
}
private global::System.IServiceProvider? Fallback => null;
public object? GetService(global::System.Type serviceType)
=> GetKeyedService(serviceType, null);
public object? GetKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, false)
?? (serviceKey == null ? Fallback?.GetService(serviceType) : (Fallback as global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider)?.GetKeyedService(serviceType, serviceKey));
public object GetRequiredKeyedService(global::System.Type serviceType, object? serviceKey)
=> GetKeyedService(serviceType, serviceKey)
?? throw new global::System.InvalidOperationException("No service for type '" + serviceType + "' has been registered.");
public T? GetService<T>()
=> this is Container.IResolver<T> resolver ? resolver.Get() : GetService(typeof(T)) is T service ? service : default;
public T GetRequiredService<T>()
=> this is Container.IResolver<T> resolver ? resolver.Get() : (T)GetRequiredKeyedService(typeof(T), null);
global::IClock Container.IResolver<global::IClock>.Get()
=> S0();
global::IGreeter Container.IResolver<global::IGreeter>.Get()
=> S1();
global::System.Collections.Generic.IEnumerable<global::IClock> Container.IResolver<global::System.Collections.Generic.IEnumerable<global::IClock>>.Get()
=> new global::IClock[] { S0() };
global::System.Collections.Generic.IEnumerable<global::IGreeter> Container.IResolver<global::System.Collections.Generic.IEnumerable<global::IGreeter>>.Get()
=> new global::IGreeter[] { S1() };
global::System.IServiceProvider Container.IResolver<global::System.IServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService Container.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>.Get()
=> this;
public bool IsService(global::System.Type serviceType)
=> IsKeyedService(serviceType, null);
public bool IsKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, true) != null || (serviceKey == null ? (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)?.IsService(serviceType) == true : (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)?.IsKeyedService(serviceType, serviceKey) == true);
public Scope CreateScope() => new Scope(_root);
global::Microsoft.Extensions.DependencyInjection.IServiceScope global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory.CreateScope() => CreateScope();
private static T Required<T>(object? service)
=> service is T t ? t : throw new global::System.InvalidOperationException("No service for type '" + typeof(T) + "' has been registered.");
private T Track<T>(T service)
{
if (service is global::System.IDisposable)
lock (_lock)
(_disposables ??= new global::System.Collections.Generic.List<object>()).Add(service);
return service;
}
private object[] Drain()
{
lock (_lock)
{
var items = _disposables?.ToArray() ?? new object[0];
_disposables = null;
global::System.Array.Reverse(items);
return items;
}
}
public void Dispose()
{
foreach (var item in Drain())
{
if (item is global::System.IDisposable disposable)
{
disposable.Dispose();
}
}
}
}
}
Add [ServiceProvider] to a blank partial class and register services with [Singleton], [Transient] or [Scoped] attributes.
The service provider is fully generated at compile time so there is no runtime reflection.
Multiple registrations for the same service can be returned with IEnumerable<T>. When getting just one the last registration wins.
Scanning
As well as registering services individually there is also an option to scan for services. Scanning is performed at compile time.
[ServiceProvider]
[ScanTransient(typeof(IHandler<>))]
public sealed partial class OrderContainer;
public interface IHandler<TMessage>;
public class CreateOrderHandler : IHandler<CreateOrder>;
public class CancelOrderHandler : IHandler<CancelOrder>;
What gets generated
//HintName: OrderContainer.ServiceProvider.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/distantcam/AutoCtor
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
partial class OrderContainer :
global::System.IServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService,
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService,
global::System.IDisposable,
OrderContainer.IResolver<global::IHandler<global::CancelOrder>>,
OrderContainer.IResolver<global::IHandler<global::CreateOrder>>,
OrderContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IHandler<global::CancelOrder>>>,
OrderContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IHandler<global::CreateOrder>>>,
OrderContainer.IResolver<global::System.IServiceProvider>,
OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>,
OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>,
OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>,
OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>
{
private readonly object _lock = new object();
private global::System.Collections.Generic.List<object>? _disposables;
private global::IHandler<global::CancelOrder> S0() => new global::CancelOrderHandler();
private global::IHandler<global::CreateOrder> S1() => new global::CreateOrderHandler();
private object? Resolve(global::System.Type type, object? key, bool probe)
{
if (key is null)
{
if (type == typeof(global::IHandler<global::CancelOrder>))
return probe ? this : (object)(S0());
if (type == typeof(global::IHandler<global::CreateOrder>))
return probe ? this : (object)(S1());
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IHandler<global::CancelOrder>>))
return probe ? this : (object)(new global::IHandler<global::CancelOrder>[] { S0() });
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IHandler<global::CreateOrder>>))
return probe ? this : (object)(new global::IHandler<global::CreateOrder>[] { S1() });
if (type == typeof(global::System.IServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService))
return probe ? this : (object)(this);
return null;
}
return null;
}
private global::System.IServiceProvider? Fallback => null;
public object? GetService(global::System.Type serviceType)
=> GetKeyedService(serviceType, null);
public object? GetKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, false)
?? (serviceKey == null ? Fallback?.GetService(serviceType) : (Fallback as global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider)?.GetKeyedService(serviceType, serviceKey));
public object GetRequiredKeyedService(global::System.Type serviceType, object? serviceKey)
=> GetKeyedService(serviceType, serviceKey)
?? throw new global::System.InvalidOperationException("No service for type '" + serviceType + "' has been registered.");
public T? GetService<T>()
=> this is OrderContainer.IResolver<T> resolver ? resolver.Get() : GetService(typeof(T)) is T service ? service : default;
public T GetRequiredService<T>()
=> this is OrderContainer.IResolver<T> resolver ? resolver.Get() : (T)GetRequiredKeyedService(typeof(T), null);
private interface IResolver<T> { T Get(); }
global::IHandler<global::CancelOrder> OrderContainer.IResolver<global::IHandler<global::CancelOrder>>.Get()
=> S0();
global::IHandler<global::CreateOrder> OrderContainer.IResolver<global::IHandler<global::CreateOrder>>.Get()
=> S1();
global::System.Collections.Generic.IEnumerable<global::IHandler<global::CancelOrder>> OrderContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IHandler<global::CancelOrder>>>.Get()
=> new global::IHandler<global::CancelOrder>[] { S0() };
global::System.Collections.Generic.IEnumerable<global::IHandler<global::CreateOrder>> OrderContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IHandler<global::CreateOrder>>>.Get()
=> new global::IHandler<global::CreateOrder>[] { S1() };
global::System.IServiceProvider OrderContainer.IResolver<global::System.IServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>.Get()
=> this;
public bool IsService(global::System.Type serviceType)
=> IsKeyedService(serviceType, null);
public bool IsKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, true) != null || (serviceKey == null ? (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)?.IsService(serviceType) == true : (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)?.IsKeyedService(serviceType, serviceKey) == true);
public Scope CreateScope() => new Scope(this);
global::Microsoft.Extensions.DependencyInjection.IServiceScope global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory.CreateScope() => CreateScope();
private static T Required<T>(object? service)
=> service is T t ? t : throw new global::System.InvalidOperationException("No service for type '" + typeof(T) + "' has been registered.");
private T Track<T>(T service)
{
if (service is global::System.IDisposable)
lock (_lock)
(_disposables ??= new global::System.Collections.Generic.List<object>()).Add(service);
return service;
}
private object[] Drain()
{
lock (_lock)
{
var items = _disposables?.ToArray() ?? new object[0];
_disposables = null;
global::System.Array.Reverse(items);
return items;
}
}
public void Dispose()
{
foreach (var item in Drain())
{
if (item is global::System.IDisposable disposable)
{
disposable.Dispose();
}
}
}
[global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")]
public sealed class Scope :
global::System.IServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService,
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService,
global::System.IDisposable,
global::Microsoft.Extensions.DependencyInjection.IServiceScope,
OrderContainer.IResolver<global::IHandler<global::CancelOrder>>,
OrderContainer.IResolver<global::IHandler<global::CreateOrder>>,
OrderContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IHandler<global::CancelOrder>>>,
OrderContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IHandler<global::CreateOrder>>>,
OrderContainer.IResolver<global::System.IServiceProvider>,
OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>,
OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>,
OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>,
OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>
{
private readonly object _lock = new object();
private global::System.Collections.Generic.List<object>? _disposables;
private readonly OrderContainer _root;
public Scope(OrderContainer root) => _root = root;
public global::System.IServiceProvider ServiceProvider => this;
private global::IHandler<global::CancelOrder> S0() => new global::CancelOrderHandler();
private global::IHandler<global::CreateOrder> S1() => new global::CreateOrderHandler();
private object? Resolve(global::System.Type type, object? key, bool probe)
{
if (key is null)
{
if (type == typeof(global::IHandler<global::CancelOrder>))
return probe ? this : (object)(S0());
if (type == typeof(global::IHandler<global::CreateOrder>))
return probe ? this : (object)(S1());
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IHandler<global::CancelOrder>>))
return probe ? this : (object)(new global::IHandler<global::CancelOrder>[] { S0() });
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IHandler<global::CreateOrder>>))
return probe ? this : (object)(new global::IHandler<global::CreateOrder>[] { S1() });
if (type == typeof(global::System.IServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService))
return probe ? this : (object)(this);
return null;
}
return null;
}
private global::System.IServiceProvider? Fallback => null;
public object? GetService(global::System.Type serviceType)
=> GetKeyedService(serviceType, null);
public object? GetKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, false)
?? (serviceKey == null ? Fallback?.GetService(serviceType) : (Fallback as global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider)?.GetKeyedService(serviceType, serviceKey));
public object GetRequiredKeyedService(global::System.Type serviceType, object? serviceKey)
=> GetKeyedService(serviceType, serviceKey)
?? throw new global::System.InvalidOperationException("No service for type '" + serviceType + "' has been registered.");
public T? GetService<T>()
=> this is OrderContainer.IResolver<T> resolver ? resolver.Get() : GetService(typeof(T)) is T service ? service : default;
public T GetRequiredService<T>()
=> this is OrderContainer.IResolver<T> resolver ? resolver.Get() : (T)GetRequiredKeyedService(typeof(T), null);
global::IHandler<global::CancelOrder> OrderContainer.IResolver<global::IHandler<global::CancelOrder>>.Get()
=> S0();
global::IHandler<global::CreateOrder> OrderContainer.IResolver<global::IHandler<global::CreateOrder>>.Get()
=> S1();
global::System.Collections.Generic.IEnumerable<global::IHandler<global::CancelOrder>> OrderContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IHandler<global::CancelOrder>>>.Get()
=> new global::IHandler<global::CancelOrder>[] { S0() };
global::System.Collections.Generic.IEnumerable<global::IHandler<global::CreateOrder>> OrderContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IHandler<global::CreateOrder>>>.Get()
=> new global::IHandler<global::CreateOrder>[] { S1() };
global::System.IServiceProvider OrderContainer.IResolver<global::System.IServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService OrderContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>.Get()
=> this;
public bool IsService(global::System.Type serviceType)
=> IsKeyedService(serviceType, null);
public bool IsKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, true) != null || (serviceKey == null ? (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)?.IsService(serviceType) == true : (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)?.IsKeyedService(serviceType, serviceKey) == true);
public Scope CreateScope() => new Scope(_root);
global::Microsoft.Extensions.DependencyInjection.IServiceScope global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory.CreateScope() => CreateScope();
private static T Required<T>(object? service)
=> service is T t ? t : throw new global::System.InvalidOperationException("No service for type '" + typeof(T) + "' has been registered.");
private T Track<T>(T service)
{
if (service is global::System.IDisposable)
lock (_lock)
(_disposables ??= new global::System.Collections.Generic.List<object>()).Add(service);
return service;
}
private object[] Drain()
{
lock (_lock)
{
var items = _disposables?.ToArray() ?? new object[0];
_disposables = null;
global::System.Array.Reverse(items);
return items;
}
}
public void Dispose()
{
foreach (var item in Drain())
{
if (item is global::System.IDisposable disposable)
{
disposable.Dispose();
}
}
}
}
}
The scan attributes [ScanSingleton], [ScanTransient], and [ScanScoped] have some options.
Asdetermines what to register the service as:ScanAs.Service, the service being scanned for (default);ScanAs.Self, the type itself;ScanAs.ImplementedInterfaces, all the interfaces the type has.FromAssembliesOfcan be used to scan other assemblies instead of the one the provider is in; add the provider too to keep it in the list of assemblies to scan.TypeNameFilteronly includes types whose name matches, where*matches anything and?any one character, e.g."*Repository". The service can be left out to select by name alone.
Keyed Services
[ServiceProvider]
[Singleton<IClient, LiveClient>(Key = "live")]
[Singleton<IClient, SandboxClient>(Key = "sandbox")]
[Singleton<IPaymentGateway, PaymentGateway>]
public sealed partial class PaymentContainer;
public interface IPaymentGateway;
public class PaymentGateway : IPaymentGateway
{
public PaymentGateway([AutoKeyedService("live")] IClient client) { }
}
What gets generated
//HintName: PaymentContainer.ServiceProvider.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/distantcam/AutoCtor
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
partial class PaymentContainer :
global::System.IServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService,
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService,
global::System.IDisposable,
PaymentContainer.IResolver<global::IPaymentGateway>,
PaymentContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IPaymentGateway>>,
PaymentContainer.IResolver<global::System.IServiceProvider>,
PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>,
PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>,
PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>,
PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>
{
private readonly object _lock = new object();
private global::System.Collections.Generic.List<object>? _disposables;
private volatile global::IClient? _S0;
private global::IClient S0()
{
var service = _S0;
if (service is not null)
return service;
lock (_lock)
return (_S0 ??= new global::LiveClient());
}
private volatile global::IClient? _S1;
private global::IClient S1()
{
var service = _S1;
if (service is not null)
return service;
lock (_lock)
return (_S1 ??= new global::SandboxClient());
}
private volatile global::IPaymentGateway? _S2;
private global::IPaymentGateway S2()
{
var service = _S2;
if (service is not null)
return service;
lock (_lock)
return (_S2 ??= new global::PaymentGateway(S0()));
}
private object? Resolve(global::System.Type type, object? key, bool probe)
{
if (key is null)
{
if (type == typeof(global::IPaymentGateway))
return probe ? this : (object)(S2());
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IPaymentGateway>))
return probe ? this : (object)(new global::IPaymentGateway[] { S2() });
if (type == typeof(global::System.IServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService))
return probe ? this : (object)(this);
return null;
}
if (type == typeof(global::IClient) && object.Equals(key, "live"))
return probe ? this : (object)(S0());
if (type == typeof(global::IClient) && object.Equals(key, "sandbox"))
return probe ? this : (object)(S1());
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IClient>) && object.Equals(key, "live"))
return probe ? this : (object)(new global::IClient[] { S0() });
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IClient>) && object.Equals(key, "sandbox"))
return probe ? this : (object)(new global::IClient[] { S1() });
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IClient>) && object.Equals(key, global::Microsoft.Extensions.DependencyInjection.KeyedService.AnyKey))
return probe ? this : (object)(new global::IClient[] { S0(), S1() });
return null;
}
private global::System.IServiceProvider? Fallback => null;
public object? GetService(global::System.Type serviceType)
=> GetKeyedService(serviceType, null);
public object? GetKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, false)
?? (serviceKey == null ? Fallback?.GetService(serviceType) : (Fallback as global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider)?.GetKeyedService(serviceType, serviceKey));
public object GetRequiredKeyedService(global::System.Type serviceType, object? serviceKey)
=> GetKeyedService(serviceType, serviceKey)
?? throw new global::System.InvalidOperationException("No service for type '" + serviceType + "' has been registered.");
public T? GetService<T>()
=> this is PaymentContainer.IResolver<T> resolver ? resolver.Get() : GetService(typeof(T)) is T service ? service : default;
public T GetRequiredService<T>()
=> this is PaymentContainer.IResolver<T> resolver ? resolver.Get() : (T)GetRequiredKeyedService(typeof(T), null);
private interface IResolver<T> { T Get(); }
global::IPaymentGateway PaymentContainer.IResolver<global::IPaymentGateway>.Get()
=> S2();
global::System.Collections.Generic.IEnumerable<global::IPaymentGateway> PaymentContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IPaymentGateway>>.Get()
=> new global::IPaymentGateway[] { S2() };
global::System.IServiceProvider PaymentContainer.IResolver<global::System.IServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>.Get()
=> this;
public bool IsService(global::System.Type serviceType)
=> IsKeyedService(serviceType, null);
public bool IsKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, true) != null || (serviceKey == null ? (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)?.IsService(serviceType) == true : (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)?.IsKeyedService(serviceType, serviceKey) == true);
public Scope CreateScope() => new Scope(this);
global::Microsoft.Extensions.DependencyInjection.IServiceScope global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory.CreateScope() => CreateScope();
private static T Required<T>(object? service)
=> service is T t ? t : throw new global::System.InvalidOperationException("No service for type '" + typeof(T) + "' has been registered.");
private T Track<T>(T service)
{
if (service is global::System.IDisposable)
lock (_lock)
(_disposables ??= new global::System.Collections.Generic.List<object>()).Add(service);
return service;
}
private object[] Drain()
{
lock (_lock)
{
var items = _disposables?.ToArray() ?? new object[0];
_disposables = null;
global::System.Array.Reverse(items);
return items;
}
}
public void Dispose()
{
foreach (var item in Drain())
{
if (item is global::System.IDisposable disposable)
{
disposable.Dispose();
}
}
}
[global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")]
public sealed class Scope :
global::System.IServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService,
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService,
global::System.IDisposable,
global::Microsoft.Extensions.DependencyInjection.IServiceScope,
PaymentContainer.IResolver<global::IPaymentGateway>,
PaymentContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IPaymentGateway>>,
PaymentContainer.IResolver<global::System.IServiceProvider>,
PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>,
PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>,
PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>,
PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>
{
private readonly object _lock = new object();
private global::System.Collections.Generic.List<object>? _disposables;
private readonly PaymentContainer _root;
public Scope(PaymentContainer root) => _root = root;
public global::System.IServiceProvider ServiceProvider => this;
private global::IClient S0() => _root.S0();
private global::IClient S1() => _root.S1();
private global::IPaymentGateway S2() => _root.S2();
private object? Resolve(global::System.Type type, object? key, bool probe)
{
if (key is null)
{
if (type == typeof(global::IPaymentGateway))
return probe ? this : (object)(S2());
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IPaymentGateway>))
return probe ? this : (object)(new global::IPaymentGateway[] { S2() });
if (type == typeof(global::System.IServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService))
return probe ? this : (object)(this);
return null;
}
if (type == typeof(global::IClient) && object.Equals(key, "live"))
return probe ? this : (object)(S0());
if (type == typeof(global::IClient) && object.Equals(key, "sandbox"))
return probe ? this : (object)(S1());
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IClient>) && object.Equals(key, "live"))
return probe ? this : (object)(new global::IClient[] { S0() });
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IClient>) && object.Equals(key, "sandbox"))
return probe ? this : (object)(new global::IClient[] { S1() });
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IClient>) && object.Equals(key, global::Microsoft.Extensions.DependencyInjection.KeyedService.AnyKey))
return probe ? this : (object)(new global::IClient[] { S0(), S1() });
return null;
}
private global::System.IServiceProvider? Fallback => null;
public object? GetService(global::System.Type serviceType)
=> GetKeyedService(serviceType, null);
public object? GetKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, false)
?? (serviceKey == null ? Fallback?.GetService(serviceType) : (Fallback as global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider)?.GetKeyedService(serviceType, serviceKey));
public object GetRequiredKeyedService(global::System.Type serviceType, object? serviceKey)
=> GetKeyedService(serviceType, serviceKey)
?? throw new global::System.InvalidOperationException("No service for type '" + serviceType + "' has been registered.");
public T? GetService<T>()
=> this is PaymentContainer.IResolver<T> resolver ? resolver.Get() : GetService(typeof(T)) is T service ? service : default;
public T GetRequiredService<T>()
=> this is PaymentContainer.IResolver<T> resolver ? resolver.Get() : (T)GetRequiredKeyedService(typeof(T), null);
global::IPaymentGateway PaymentContainer.IResolver<global::IPaymentGateway>.Get()
=> S2();
global::System.Collections.Generic.IEnumerable<global::IPaymentGateway> PaymentContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IPaymentGateway>>.Get()
=> new global::IPaymentGateway[] { S2() };
global::System.IServiceProvider PaymentContainer.IResolver<global::System.IServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService PaymentContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>.Get()
=> this;
public bool IsService(global::System.Type serviceType)
=> IsKeyedService(serviceType, null);
public bool IsKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, true) != null || (serviceKey == null ? (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)?.IsService(serviceType) == true : (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)?.IsKeyedService(serviceType, serviceKey) == true);
public Scope CreateScope() => new Scope(_root);
global::Microsoft.Extensions.DependencyInjection.IServiceScope global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory.CreateScope() => CreateScope();
private static T Required<T>(object? service)
=> service is T t ? t : throw new global::System.InvalidOperationException("No service for type '" + typeof(T) + "' has been registered.");
private T Track<T>(T service)
{
if (service is global::System.IDisposable)
lock (_lock)
(_disposables ??= new global::System.Collections.Generic.List<object>()).Add(service);
return service;
}
private object[] Drain()
{
lock (_lock)
{
var items = _disposables?.ToArray() ?? new object[0];
_disposables = null;
global::System.Array.Reverse(items);
return items;
}
}
public void Dispose()
{
foreach (var item in Drain())
{
if (item is global::System.IDisposable disposable)
{
disposable.Dispose();
}
}
}
}
}
Factories
[ServiceProvider]
[Singleton<IClock>(Factory = nameof(CreateClock))]
[Singleton<IBanner>(Factory = nameof(_banner))]
[Scoped<IAuditLog>(Factory = nameof(CreateAuditLog))]
public sealed partial class HostContainer
{
private readonly IBanner _banner = new Banner("AutoCtor");
private IClock CreateClock() => new SystemClock("UTC");
private IAuditLog CreateAuditLog(System.IServiceProvider services) => new AuditLog(services);
}
What gets generated
//HintName: HostContainer.ServiceProvider.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/distantcam/AutoCtor
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
partial class HostContainer :
global::System.IServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService,
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService,
global::System.IDisposable,
HostContainer.IResolver<global::IClock>,
HostContainer.IResolver<global::IBanner>,
HostContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IClock>>,
HostContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IBanner>>,
HostContainer.IResolver<global::System.IServiceProvider>,
HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>,
HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>,
HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>,
HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>
{
private readonly object _lock = new object();
private global::System.Collections.Generic.List<object>? _disposables;
private volatile global::IClock? _S0;
private global::IClock S0()
{
var service = _S0;
if (service is not null)
return service;
lock (_lock)
return (_S0 ??= Track<global::IClock>(this.CreateClock()));
}
private volatile global::IBanner? _S1;
private global::IBanner S1()
{
var service = _S1;
if (service is not null)
return service;
lock (_lock)
return (_S1 ??= Track<global::IBanner>(this._banner));
}
private object? Resolve(global::System.Type type, object? key, bool probe)
{
if (key is null)
{
if (type == typeof(global::IClock))
return probe ? this : (object)(S0());
if (type == typeof(global::IBanner))
return probe ? this : (object)(S1());
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IClock>))
return probe ? this : (object)(new global::IClock[] { S0() });
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IBanner>))
return probe ? this : (object)(new global::IBanner[] { S1() });
if (type == typeof(global::System.IServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService))
return probe ? this : (object)(this);
return null;
}
return null;
}
private global::System.IServiceProvider? Fallback => null;
public object? GetService(global::System.Type serviceType)
=> GetKeyedService(serviceType, null);
public object? GetKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, false)
?? (serviceKey == null ? Fallback?.GetService(serviceType) : (Fallback as global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider)?.GetKeyedService(serviceType, serviceKey));
public object GetRequiredKeyedService(global::System.Type serviceType, object? serviceKey)
=> GetKeyedService(serviceType, serviceKey)
?? throw new global::System.InvalidOperationException("No service for type '" + serviceType + "' has been registered.");
public T? GetService<T>()
=> this is HostContainer.IResolver<T> resolver ? resolver.Get() : GetService(typeof(T)) is T service ? service : default;
public T GetRequiredService<T>()
=> this is HostContainer.IResolver<T> resolver ? resolver.Get() : (T)GetRequiredKeyedService(typeof(T), null);
private interface IResolver<T> { T Get(); }
global::IClock HostContainer.IResolver<global::IClock>.Get()
=> S0();
global::IBanner HostContainer.IResolver<global::IBanner>.Get()
=> S1();
global::System.Collections.Generic.IEnumerable<global::IClock> HostContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IClock>>.Get()
=> new global::IClock[] { S0() };
global::System.Collections.Generic.IEnumerable<global::IBanner> HostContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IBanner>>.Get()
=> new global::IBanner[] { S1() };
global::System.IServiceProvider HostContainer.IResolver<global::System.IServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>.Get()
=> this;
public bool IsService(global::System.Type serviceType)
=> IsKeyedService(serviceType, null);
public bool IsKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, true) != null || (serviceKey == null ? (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)?.IsService(serviceType) == true : (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)?.IsKeyedService(serviceType, serviceKey) == true);
public Scope CreateScope() => new Scope(this);
global::Microsoft.Extensions.DependencyInjection.IServiceScope global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory.CreateScope() => CreateScope();
private static T Required<T>(object? service)
=> service is T t ? t : throw new global::System.InvalidOperationException("No service for type '" + typeof(T) + "' has been registered.");
private T Track<T>(T service)
{
if (service is global::System.IDisposable)
lock (_lock)
(_disposables ??= new global::System.Collections.Generic.List<object>()).Add(service);
return service;
}
private object[] Drain()
{
lock (_lock)
{
var items = _disposables?.ToArray() ?? new object[0];
_disposables = null;
global::System.Array.Reverse(items);
return items;
}
}
public void Dispose()
{
foreach (var item in Drain())
{
if (item is global::System.IDisposable disposable)
{
disposable.Dispose();
}
}
}
[global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")]
public sealed class Scope :
global::System.IServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService,
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService,
global::System.IDisposable,
global::Microsoft.Extensions.DependencyInjection.IServiceScope,
HostContainer.IResolver<global::IClock>,
HostContainer.IResolver<global::IBanner>,
HostContainer.IResolver<global::IAuditLog>,
HostContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IClock>>,
HostContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IBanner>>,
HostContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IAuditLog>>,
HostContainer.IResolver<global::System.IServiceProvider>,
HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>,
HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>,
HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>,
HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>
{
private readonly object _lock = new object();
private global::System.Collections.Generic.List<object>? _disposables;
private readonly HostContainer _root;
public Scope(HostContainer root) => _root = root;
public global::System.IServiceProvider ServiceProvider => this;
private global::IClock S0() => _root.S0();
private global::IBanner S1() => _root.S1();
private volatile global::IAuditLog? _S2;
private global::IAuditLog S2()
{
var service = _S2;
if (service is not null)
return service;
lock (_lock)
return (_S2 ??= Track<global::IAuditLog>(_root.CreateAuditLog(this)));
}
private object? Resolve(global::System.Type type, object? key, bool probe)
{
if (key is null)
{
if (type == typeof(global::IClock))
return probe ? this : (object)(S0());
if (type == typeof(global::IBanner))
return probe ? this : (object)(S1());
if (type == typeof(global::IAuditLog))
return probe ? this : (object)(S2());
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IClock>))
return probe ? this : (object)(new global::IClock[] { S0() });
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IBanner>))
return probe ? this : (object)(new global::IBanner[] { S1() });
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IAuditLog>))
return probe ? this : (object)(new global::IAuditLog[] { S2() });
if (type == typeof(global::System.IServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService))
return probe ? this : (object)(this);
return null;
}
return null;
}
private global::System.IServiceProvider? Fallback => null;
public object? GetService(global::System.Type serviceType)
=> GetKeyedService(serviceType, null);
public object? GetKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, false)
?? (serviceKey == null ? Fallback?.GetService(serviceType) : (Fallback as global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider)?.GetKeyedService(serviceType, serviceKey));
public object GetRequiredKeyedService(global::System.Type serviceType, object? serviceKey)
=> GetKeyedService(serviceType, serviceKey)
?? throw new global::System.InvalidOperationException("No service for type '" + serviceType + "' has been registered.");
public T? GetService<T>()
=> this is HostContainer.IResolver<T> resolver ? resolver.Get() : GetService(typeof(T)) is T service ? service : default;
public T GetRequiredService<T>()
=> this is HostContainer.IResolver<T> resolver ? resolver.Get() : (T)GetRequiredKeyedService(typeof(T), null);
global::IClock HostContainer.IResolver<global::IClock>.Get()
=> S0();
global::IBanner HostContainer.IResolver<global::IBanner>.Get()
=> S1();
global::IAuditLog HostContainer.IResolver<global::IAuditLog>.Get()
=> S2();
global::System.Collections.Generic.IEnumerable<global::IClock> HostContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IClock>>.Get()
=> new global::IClock[] { S0() };
global::System.Collections.Generic.IEnumerable<global::IBanner> HostContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IBanner>>.Get()
=> new global::IBanner[] { S1() };
global::System.Collections.Generic.IEnumerable<global::IAuditLog> HostContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IAuditLog>>.Get()
=> new global::IAuditLog[] { S2() };
global::System.IServiceProvider HostContainer.IResolver<global::System.IServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService HostContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>.Get()
=> this;
public bool IsService(global::System.Type serviceType)
=> IsKeyedService(serviceType, null);
public bool IsKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, true) != null || (serviceKey == null ? (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)?.IsService(serviceType) == true : (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)?.IsKeyedService(serviceType, serviceKey) == true);
public Scope CreateScope() => new Scope(_root);
global::Microsoft.Extensions.DependencyInjection.IServiceScope global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory.CreateScope() => CreateScope();
private static T Required<T>(object? service)
=> service is T t ? t : throw new global::System.InvalidOperationException("No service for type '" + typeof(T) + "' has been registered.");
private T Track<T>(T service)
{
if (service is global::System.IDisposable)
lock (_lock)
(_disposables ??= new global::System.Collections.Generic.List<object>()).Add(service);
return service;
}
private object[] Drain()
{
lock (_lock)
{
var items = _disposables?.ToArray() ?? new object[0];
_disposables = null;
global::System.Array.Reverse(items);
return items;
}
}
public void Dispose()
{
foreach (var item in Drain())
{
if (item is global::System.IDisposable disposable)
{
disposable.Dispose();
}
}
}
}
}
Falling back to another provider
Fallback on [ServiceProvider] names a member to use when there is no registration for that service.
[ServiceProvider(Fallback = nameof(_host))]
[Singleton<IGreeter, Greeter>]
public sealed partial class FallbackContainer
{
private readonly System.IServiceProvider _host;
public FallbackContainer(System.IServiceProvider host) => _host = host;
}
What gets generated
//HintName: FallbackContainer.ServiceProvider.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/distantcam/AutoCtor
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
partial class FallbackContainer :
global::System.IServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService,
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService,
global::System.IDisposable,
FallbackContainer.IResolver<global::IGreeter>,
FallbackContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IGreeter>>,
FallbackContainer.IResolver<global::System.IServiceProvider>,
FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>,
FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>,
FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>,
FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>
{
private readonly object _lock = new object();
private global::System.Collections.Generic.List<object>? _disposables;
private volatile global::IGreeter? _S0;
private global::IGreeter S0()
{
var service = _S0;
if (service is not null)
return service;
lock (_lock)
return (_S0 ??= new global::Greeter(Required<global::ILogSink>(GetKeyedService(typeof(global::ILogSink), null))));
}
private object? Resolve(global::System.Type type, object? key, bool probe)
{
if (key is null)
{
if (type == typeof(global::IGreeter))
return probe ? this : (object)(S0());
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IGreeter>))
return probe ? this : (object)(new global::IGreeter[] { S0() });
if (type == typeof(global::System.IServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService))
return probe ? this : (object)(this);
return null;
}
return null;
}
private global::System.IServiceProvider? Fallback => this._host;
public object? GetService(global::System.Type serviceType)
=> GetKeyedService(serviceType, null);
public object? GetKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, false)
?? (serviceKey == null ? Fallback?.GetService(serviceType) : (Fallback as global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider)?.GetKeyedService(serviceType, serviceKey));
public object GetRequiredKeyedService(global::System.Type serviceType, object? serviceKey)
=> GetKeyedService(serviceType, serviceKey)
?? throw new global::System.InvalidOperationException("No service for type '" + serviceType + "' has been registered.");
public T? GetService<T>()
=> this is FallbackContainer.IResolver<T> resolver ? resolver.Get() : GetService(typeof(T)) is T service ? service : default;
public T GetRequiredService<T>()
=> this is FallbackContainer.IResolver<T> resolver ? resolver.Get() : (T)GetRequiredKeyedService(typeof(T), null);
private interface IResolver<T> { T Get(); }
global::IGreeter FallbackContainer.IResolver<global::IGreeter>.Get()
=> S0();
global::System.Collections.Generic.IEnumerable<global::IGreeter> FallbackContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IGreeter>>.Get()
=> new global::IGreeter[] { S0() };
global::System.IServiceProvider FallbackContainer.IResolver<global::System.IServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>.Get()
=> this;
public bool IsService(global::System.Type serviceType)
=> IsKeyedService(serviceType, null);
public bool IsKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, true) != null || (serviceKey == null ? (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)?.IsService(serviceType) == true : (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)?.IsKeyedService(serviceType, serviceKey) == true);
public Scope CreateScope() => new Scope(this);
global::Microsoft.Extensions.DependencyInjection.IServiceScope global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory.CreateScope() => CreateScope();
private static T Required<T>(object? service)
=> service is T t ? t : throw new global::System.InvalidOperationException("No service for type '" + typeof(T) + "' has been registered.");
private T Track<T>(T service)
{
if (service is global::System.IDisposable)
lock (_lock)
(_disposables ??= new global::System.Collections.Generic.List<object>()).Add(service);
return service;
}
private object[] Drain()
{
lock (_lock)
{
var items = _disposables?.ToArray() ?? new object[0];
_disposables = null;
global::System.Array.Reverse(items);
return items;
}
}
public void Dispose()
{
foreach (var item in Drain())
{
if (item is global::System.IDisposable disposable)
{
disposable.Dispose();
}
}
}
[global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")]
public sealed class Scope :
global::System.IServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService,
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService,
global::System.IDisposable,
global::Microsoft.Extensions.DependencyInjection.IServiceScope,
FallbackContainer.IResolver<global::IGreeter>,
FallbackContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IGreeter>>,
FallbackContainer.IResolver<global::System.IServiceProvider>,
FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>,
FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>,
FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>,
FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>
{
private readonly object _lock = new object();
private global::System.Collections.Generic.List<object>? _disposables;
private readonly FallbackContainer _root;
public Scope(FallbackContainer root) => _root = root;
public global::System.IServiceProvider ServiceProvider => this;
private global::IGreeter S0() => _root.S0();
private object? Resolve(global::System.Type type, object? key, bool probe)
{
if (key is null)
{
if (type == typeof(global::IGreeter))
return probe ? this : (object)(S0());
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IGreeter>))
return probe ? this : (object)(new global::IGreeter[] { S0() });
if (type == typeof(global::System.IServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService))
return probe ? this : (object)(this);
return null;
}
return null;
}
private global::System.IServiceProvider? _fallback;
private global::System.IServiceProvider? Fallback { get { lock (_lock) return _fallback ??= _root._host is global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory f ? Track(f.CreateScope()).ServiceProvider : _root._host; } }
public object? GetService(global::System.Type serviceType)
=> GetKeyedService(serviceType, null);
public object? GetKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, false)
?? (serviceKey == null ? Fallback?.GetService(serviceType) : (Fallback as global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider)?.GetKeyedService(serviceType, serviceKey));
public object GetRequiredKeyedService(global::System.Type serviceType, object? serviceKey)
=> GetKeyedService(serviceType, serviceKey)
?? throw new global::System.InvalidOperationException("No service for type '" + serviceType + "' has been registered.");
public T? GetService<T>()
=> this is FallbackContainer.IResolver<T> resolver ? resolver.Get() : GetService(typeof(T)) is T service ? service : default;
public T GetRequiredService<T>()
=> this is FallbackContainer.IResolver<T> resolver ? resolver.Get() : (T)GetRequiredKeyedService(typeof(T), null);
global::IGreeter FallbackContainer.IResolver<global::IGreeter>.Get()
=> S0();
global::System.Collections.Generic.IEnumerable<global::IGreeter> FallbackContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IGreeter>>.Get()
=> new global::IGreeter[] { S0() };
global::System.IServiceProvider FallbackContainer.IResolver<global::System.IServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService FallbackContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>.Get()
=> this;
public bool IsService(global::System.Type serviceType)
=> IsKeyedService(serviceType, null);
public bool IsKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, true) != null || (serviceKey == null ? (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)?.IsService(serviceType) == true : (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)?.IsKeyedService(serviceType, serviceKey) == true);
public Scope CreateScope() => new Scope(_root);
global::Microsoft.Extensions.DependencyInjection.IServiceScope global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory.CreateScope() => CreateScope();
private static T Required<T>(object? service)
=> service is T t ? t : throw new global::System.InvalidOperationException("No service for type '" + typeof(T) + "' has been registered.");
private T Track<T>(T service)
{
if (service is global::System.IDisposable)
lock (_lock)
(_disposables ??= new global::System.Collections.Generic.List<object>()).Add(service);
return service;
}
private object[] Drain()
{
lock (_lock)
{
var items = _disposables?.ToArray() ?? new object[0];
_disposables = null;
global::System.Array.Reverse(items);
return items;
}
}
public void Dispose()
{
foreach (var item in Drain())
{
if (item is global::System.IDisposable disposable)
{
disposable.Dispose();
}
}
}
}
}
Modules
[Import<TModule>] (or [Import(typeof(TModule))]) adds all the registrations from another type. Modules just act as markers so no code is generated for them.
[Singleton<IPaymentGateway, StripeGateway>]
[Scoped<ILedger>(Factory = nameof(CreateLedger))]
public class PaymentsModule
{
public static ILedger CreateLedger(IPaymentGateway gateway) => new Ledger(gateway);
}
[ServiceProvider]
[Import<PaymentsModule>]
[Singleton<IPaymentGateway, FakeGateway>]
public sealed partial class TestContainer;
What gets generated
//HintName: TestContainer.ServiceProvider.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/distantcam/AutoCtor
// </auto-generated>
//------------------------------------------------------------------------------
#nullable enable
partial class TestContainer :
global::System.IServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService,
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService,
global::System.IDisposable,
TestContainer.IResolver<global::IPaymentGateway>,
TestContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IPaymentGateway>>,
TestContainer.IResolver<global::System.IServiceProvider>,
TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>,
TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>,
TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>,
TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>
{
private readonly object _lock = new object();
private global::System.Collections.Generic.List<object>? _disposables;
private volatile global::IPaymentGateway? _S0;
private global::IPaymentGateway S0()
{
var service = _S0;
if (service is not null)
return service;
lock (_lock)
return (_S0 ??= new global::StripeGateway());
}
private volatile global::IPaymentGateway? _S2;
private global::IPaymentGateway S2()
{
var service = _S2;
if (service is not null)
return service;
lock (_lock)
return (_S2 ??= new global::FakeGateway());
}
private object? Resolve(global::System.Type type, object? key, bool probe)
{
if (key is null)
{
if (type == typeof(global::IPaymentGateway))
return probe ? this : (object)(S2());
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IPaymentGateway>))
return probe ? this : (object)(new global::IPaymentGateway[] { S0(), S2() });
if (type == typeof(global::System.IServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService))
return probe ? this : (object)(this);
return null;
}
return null;
}
private global::System.IServiceProvider? Fallback => null;
public object? GetService(global::System.Type serviceType)
=> GetKeyedService(serviceType, null);
public object? GetKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, false)
?? (serviceKey == null ? Fallback?.GetService(serviceType) : (Fallback as global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider)?.GetKeyedService(serviceType, serviceKey));
public object GetRequiredKeyedService(global::System.Type serviceType, object? serviceKey)
=> GetKeyedService(serviceType, serviceKey)
?? throw new global::System.InvalidOperationException("No service for type '" + serviceType + "' has been registered.");
public T? GetService<T>()
=> this is TestContainer.IResolver<T> resolver ? resolver.Get() : GetService(typeof(T)) is T service ? service : default;
public T GetRequiredService<T>()
=> this is TestContainer.IResolver<T> resolver ? resolver.Get() : (T)GetRequiredKeyedService(typeof(T), null);
private interface IResolver<T> { T Get(); }
global::IPaymentGateway TestContainer.IResolver<global::IPaymentGateway>.Get()
=> S2();
global::System.Collections.Generic.IEnumerable<global::IPaymentGateway> TestContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IPaymentGateway>>.Get()
=> new global::IPaymentGateway[] { S0(), S2() };
global::System.IServiceProvider TestContainer.IResolver<global::System.IServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>.Get()
=> this;
public bool IsService(global::System.Type serviceType)
=> IsKeyedService(serviceType, null);
public bool IsKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, true) != null || (serviceKey == null ? (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)?.IsService(serviceType) == true : (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)?.IsKeyedService(serviceType, serviceKey) == true);
public Scope CreateScope() => new Scope(this);
global::Microsoft.Extensions.DependencyInjection.IServiceScope global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory.CreateScope() => CreateScope();
private static T Required<T>(object? service)
=> service is T t ? t : throw new global::System.InvalidOperationException("No service for type '" + typeof(T) + "' has been registered.");
private T Track<T>(T service)
{
if (service is global::System.IDisposable)
lock (_lock)
(_disposables ??= new global::System.Collections.Generic.List<object>()).Add(service);
return service;
}
private object[] Drain()
{
lock (_lock)
{
var items = _disposables?.ToArray() ?? new object[0];
_disposables = null;
global::System.Array.Reverse(items);
return items;
}
}
public void Dispose()
{
foreach (var item in Drain())
{
if (item is global::System.IDisposable disposable)
{
disposable.Dispose();
}
}
}
[global::System.CodeDom.Compiler.GeneratedCode("AutoCtor", "0.0.0.0")]
public sealed class Scope :
global::System.IServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService,
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider,
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService,
global::System.IDisposable,
global::Microsoft.Extensions.DependencyInjection.IServiceScope,
TestContainer.IResolver<global::IPaymentGateway>,
TestContainer.IResolver<global::ILedger>,
TestContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IPaymentGateway>>,
TestContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::ILedger>>,
TestContainer.IResolver<global::System.IServiceProvider>,
TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>,
TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>,
TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>,
TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>
{
private readonly object _lock = new object();
private global::System.Collections.Generic.List<object>? _disposables;
private readonly TestContainer _root;
public Scope(TestContainer root) => _root = root;
public global::System.IServiceProvider ServiceProvider => this;
private global::IPaymentGateway S0() => _root.S0();
private volatile global::ILedger? _S1;
private global::ILedger S1()
{
var service = _S1;
if (service is not null)
return service;
lock (_lock)
return (_S1 ??= Track<global::ILedger>(global::PaymentsModule.CreateLedger(S2())));
}
private global::IPaymentGateway S2() => _root.S2();
private object? Resolve(global::System.Type type, object? key, bool probe)
{
if (key is null)
{
if (type == typeof(global::IPaymentGateway))
return probe ? this : (object)(S2());
if (type == typeof(global::ILedger))
return probe ? this : (object)(S1());
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::IPaymentGateway>))
return probe ? this : (object)(new global::IPaymentGateway[] { S0(), S2() });
if (type == typeof(global::System.Collections.Generic.IEnumerable<global::ILedger>))
return probe ? this : (object)(new global::ILedger[] { S1() });
if (type == typeof(global::System.IServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider))
return probe ? this : (object)(this);
if (type == typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService))
return probe ? this : (object)(this);
return null;
}
return null;
}
private global::System.IServiceProvider? Fallback => null;
public object? GetService(global::System.Type serviceType)
=> GetKeyedService(serviceType, null);
public object? GetKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, false)
?? (serviceKey == null ? Fallback?.GetService(serviceType) : (Fallback as global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider)?.GetKeyedService(serviceType, serviceKey));
public object GetRequiredKeyedService(global::System.Type serviceType, object? serviceKey)
=> GetKeyedService(serviceType, serviceKey)
?? throw new global::System.InvalidOperationException("No service for type '" + serviceType + "' has been registered.");
public T? GetService<T>()
=> this is TestContainer.IResolver<T> resolver ? resolver.Get() : GetService(typeof(T)) is T service ? service : default;
public T GetRequiredService<T>()
=> this is TestContainer.IResolver<T> resolver ? resolver.Get() : (T)GetRequiredKeyedService(typeof(T), null);
global::IPaymentGateway TestContainer.IResolver<global::IPaymentGateway>.Get()
=> S2();
global::ILedger TestContainer.IResolver<global::ILedger>.Get()
=> S1();
global::System.Collections.Generic.IEnumerable<global::IPaymentGateway> TestContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::IPaymentGateway>>.Get()
=> new global::IPaymentGateway[] { S0(), S2() };
global::System.Collections.Generic.IEnumerable<global::ILedger> TestContainer.IResolver<global::System.Collections.Generic.IEnumerable<global::ILedger>>.Get()
=> new global::ILedger[] { S1() };
global::System.IServiceProvider TestContainer.IResolver<global::System.IServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IKeyedServiceProvider>.Get()
=> this;
global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService TestContainer.IResolver<global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService>.Get()
=> this;
public bool IsService(global::System.Type serviceType)
=> IsKeyedService(serviceType, null);
public bool IsKeyedService(global::System.Type serviceType, object? serviceKey)
=> Resolve(serviceType, serviceKey, true) != null || (serviceKey == null ? (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsService)?.IsService(serviceType) == true : (Fallback as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService ?? Fallback?.GetService(typeof(global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)) as global::Microsoft.Extensions.DependencyInjection.IServiceProviderIsKeyedService)?.IsKeyedService(serviceType, serviceKey) == true);
public Scope CreateScope() => new Scope(_root);
global::Microsoft.Extensions.DependencyInjection.IServiceScope global::Microsoft.Extensions.DependencyInjection.IServiceScopeFactory.CreateScope() => CreateScope();
private static T Required<T>(object? service)
=> service is T t ? t : throw new global::System.InvalidOperationException("No service for type '" + typeof(T) + "' has been registered.");
private T Track<T>(T service)
{
if (service is global::System.IDisposable)
lock (_lock)
(_disposables ??= new global::System.Collections.Generic.List<object>()).Add(service);
return service;
}
private object[] Drain()
{
lock (_lock)
{
var items = _disposables?.ToArray() ?? new object[0];
_disposables = null;
global::System.Array.Reverse(items);
return items;
}
}
public void Dispose()
{
foreach (var item in Drain())
{
if (item is global::System.IDisposable disposable)
{
disposable.Dispose();
}
}
}
}
}
A module can live in another assembly, but the registration attributes are [Conditional], so that assembly has to define AUTOCTOR_USAGES (see Keeping Attributes In Code) for them to be there to read.
Other
Embedding The Attributes
By default, the [AutoConstruct] attributes referenced in your project are contained in an external dll. It is also possible to embed the attributes directly in your project. To do this, you must do two things:
- Define the constant
AUTOCTOR_EMBED_ATTRIBUTES. This ensures the attributes are embedded in your project. - Add
compileto the list of excluded assets in your<PackageReference>element. This ensures the
README truncated. Read the full version on GitHub.