30
loading...
This website collects cookies to deliver better user experience
ThunderboltRegistration
as a partial class in each project where you may want to register services.dotnet add package ThunderboltIoc
Install-Package ThunderboltIoc
ThunderboltRegistration
abstract class. More on the registration can be found in the relevant section of this document.public partial class FooThunderboltRegistration : ThunderboltRegistration
{
protected override void Register(IThunderboltRegistrar reg)
{
reg.AddSingleton<BazService>();
reg.AddScoped<IBarService, BarService>();
reg.AddTransientFactory<Qux>(() => new Qux());
}
}
ThunderboltActivator.Attach<FooThunderboltRegistration>();
BazService bazService = ThunderboltActivator.Container.Get<BazService>();
Microsoft.Extensions.DependencyInjection
that was first introduced with .Net Core.IThundernoltResolver
used was not an IThunderboltScope
), a singleton service will be returned.IThunderboltScope
as the IThunderboltResolver
, each and every dependency of that service will be resolved using the same IThunderboltScope
.IThunderboltContainer
(the same as above).IThunderboltScope
This is registered as a transient service, meaning, every time you try to resolve/get an IThunderboltScope
, a new IThunderboltScope
will be created. This is the same as IThunderboltContainer.CreateScope()
.
It is worth mentioning that an IThunderboltScope
is an IDisposable
, however, that doesn't mean that disposing an IThunderboltScope
would dispose scoped instances (at least in the current release).
ThunderboltRegistration
, you will have to override the abstract void Register
. This method gives you a single argument of type IThunderboltRegistrar
(reg
), which you can use to register your services using the Add{serviceLifetime}
methods.Add{serviceLifetime}
call that happens inside (except for factory registrations), regardless of whether or not you implement a logic in your Register method (i.e even if you implement a logic where a particular call to an Add method is not reachable, code generation would still consider it anyway).reg.AddSingleton<FooService>();
reg.AddScoped<BarService>();
reg.AddTransient<BazService>();
reg.AddSingleton<IFooService, FooService>();
reg.AddScoped<IBarService, BarService>();
reg.AddTransient<IBazService, BazService>();
reg.AddSingletonFactory<FooService>();
reg.AddScopedFactory<BarService>();
reg.AddTransientFactory<BazService>();
reg.AddSingleton<IYearHalfService>(() =>
{
if (DateTime.UtcNow.Month <= 6)
return typeof(YearFirstHalfService);
else
return typeof(YearSecondHalfService);
});
return typeof(TService)
inside the scope. This means that your implementations must be known at the compile time. It is also important to notice that either this:Type fooType = typeof(FooType);
return fooType;
return someFooVariable.GetType();
() => typeof(TService)
or () => { return typeof(TService); }
) and anonymous method expressions (e.g delegate { return typeof(TService); }
).ThunderboltRegistration
for attribute registration to work. Attribute registrations are managed via two attributes (+ the regex ones): ThunderboltIncludeAttribute
andThunderboltExcludeAttribute
.FooAssembly
where you use ThunderboltIncludeAttribute
(with applyToDerivedTypes: true), and another assembly BarAssembly
that references FooAssembly
but also defines some derived types, types in BarAssembly
will not be registered (unless another ThunderboltIncludeAttribute
is defined in BarAssembly
as well).ThunderboltRegistration.Register
(even if ThunderboltIncludeAttribute
or ThunderboltRegexIncludeAttribute
is present).ThunderboltRegistration
for this to work, even if you don't have any explicit registrations. Regex attribute registrations are managed via two attributes: (ThunderboltRegexIncludeAttribute
and ThunderboltRegexExcludeAttribute
).[assembly: ThunderboltRegexIncludeAttribute(...)]
).global::Type.Full.Namespace.TypeName
).ThunderboltRegexIncludeAttribute
on the same assembly to define different patterns and lifetimes.[assembly: ThunderboltRegexInclude(
ThunderboltServiceLifetime.Scoped,
regex: @"(global::)?(MyBaseNamespace)\.I[A-Z][A-z_]+Service",
implRegex: @"(global::)?(MyBaseNamespace)\.[A-Z][a-z][A-z_]+Service",
joinKeyRegex: @"(?<=(global::)?(MyBaseNamespace)\.I?)[A-Z][a-z][A-z_]+Service")]
Get<TService>()
on an IThunderboltResolver
. An IThunderboltResolver
may either be an IThunderboltContainer
or an IThunderboltScope
.ThunderboltRegistration
via ThunderboltActivator.Attach
, it is safe to use ThunderboltActivator.Container
property to get the singleton IThunderboltContainer
instance. If you already have an IThunderboltResolver
, you may also get the same container using resolver.Get<IThunderboltContainer>()
.IThunderboltContainer
, you may create a new scope using container.CreateScope()
. If you already have an IThunderboltResolver
, you may create a new scope using resolver.Get<IThunderboltScope>()
.Microsoft.Extensions.DependencyInjection
, which to some extent limits our options when working with .Net Core projects if we wanted to utilize Microsoft's DI.Microsoft.Extensions.DependencyInjection
in the future, but it the meantime, there would be no harm in using both frameworks together side-by-sidy; that however wouldn't let us fully benefit from ThunderboltIoc's superior performance all the time.ThunderboltRegistration
does not have the partial modifier.IThunderboltScope
should in turn dispose every IDisposable
scoped service saved in the corresponding IThunderboltScope
.IServiceProvider
of Microsoft's DI. Currently, IThunderboltResolver
already implements System.IServiceProvider
but no present elegant integration exists.