Rystem.DependencyInjection
9.0.3
dotnet add package Rystem.DependencyInjection --version 9.0.3
NuGet\Install-Package Rystem.DependencyInjection -Version 9.0.3
<PackageReference Include="Rystem.DependencyInjection" Version="9.0.3" />
paket add Rystem.DependencyInjection --version 9.0.3
#r "nuget: Rystem.DependencyInjection, 9.0.3"
// Install Rystem.DependencyInjection as a Cake Addin #addin nuget:?package=Rystem.DependencyInjection&version=9.0.3 // Install Rystem.DependencyInjection as a Cake Tool #tool nuget:?package=Rystem.DependencyInjection&version=9.0.3
What is Rystem?
Get Started
Dependency injection extensions
Warm up
When you use the DI pattern in your .Net application you could need a warm up after the build of your services. And with Rystem you can simply do it.
builder.Services.AddWarmUp(() => somethingToDo());
and after the build use the warm up
var app = builder.Build();
await app.Services.WarmUpAsync();
Population service
You can use the population service to create a list of random value of a specific Type. An example from unit test explains how to use the service.
IServiceCollection services = new ServiceCollection();
services.AddPopulationService();
var serviceProvider = services.BuildServiceProvider().CreateScope().ServiceProvider;
var populatedModel = serviceProvider.GetService<IPopulation<PopulationModelTest>>();
IPopulation<PopulationModelTest> allPrepopulation = populatedModel!
.Setup()
.WithPattern(x => x.J!.First().A, "[a-z]{4,5}")
.WithPattern(x => x.Y!.First().Value.A, "[a-z]{4,5}")
.WithImplementation(x => x.I, typeof(MyInnerInterfaceImplementation))
.WithPattern(x => x.I!.A!, "[a-z]{4,5}")
.WithPattern(x => x.II!.A!, "[a-z]{4,5}")
.WithImplementation<IInnerInterface, MyInnerInterfaceImplementation>(x => x.I!);
var all = allPrepopulation.Populate();
Abstract factory
You can use this abstract factory solution when you need to setup more than one service of the same kind and you need to distinguish them by a name.
I have an interface
public interface IMyService
{
string GetName();
}
Some options for every service
public class SingletonOption
{
public string ServiceName { get; set; }
}
public class TransientOption
{
public string ServiceName { get; set; }
}
public class ScopedOption
{
public string ServiceName { get; set; }
}
with built options which is a IServiceOptions, a options class that ends up with another class. Used for example when you have to add a settings like a connection string but you want to use a service like a client that uses that connection string.
public class BuiltScopedOptions : IServiceOptions<ScopedOption>
{
public string ServiceName { get; set; }
public Task<Func<ScopedOption>> BuildAsync()
{
return Task.FromResult(() => new ScopedOption
{
ServiceName = ServiceName
});
}
}
And six different services
public class SingletonService : IMyService, IServiceWithOptions<SingletonOption>
{
public SingletonOption Options { get; set; }
public string Id { get; } = Guid.NewGuid().ToString();
public string GetName()
{
return $"{Options.ServiceName} with id {Id}";
}
}
public class TransientService : IMyService, IServiceWithOptions<TransientOption>
{
public TransientOption Options { get; set; }
public string Id { get; } = Guid.NewGuid().ToString();
public string GetName()
{
return $"{Options.ServiceName} with id {Id}";
}
}
public class ScopedService : IMyService, IServiceWithOptions<ScopedOption>
{
public ScopedOption Options { get; set; }
public string Id { get; } = Guid.NewGuid().ToString();
public string GetName()
{
return $"{Options.ServiceName} with id {Id}";
}
}
public class ScopedService2 : IMyService, IServiceWithOptions<ScopedOption>
{
public ScopedOption Options { get; set; }
public string Id { get; } = Guid.NewGuid().ToString();
public string GetName()
{
return $"{Options.ServiceName} with id {Id}";
}
}
public class ScopedService3 : IMyService, IServiceWithOptions<ScopedOption>
{
public ScopedOption Options { get; set; }
public string Id { get; } = Guid.NewGuid().ToString();
public string GetName()
{
return $"{Options.ServiceName} with id {Id}";
}
}
public class ScopedService4 : IMyService, IServiceWithOptions<ScopedOption>
{
public ScopedOption Options { get; set; }
public string Id { get; } = Guid.NewGuid().ToString();
public string GetName()
{
return $"{Options.ServiceName} with id {Id}";
}
}
I can setup them in this way
var services = new ServiceCollection();
services.AddFactory<IMyService, SingletonService, SingletonOption>(x =>
{
x.ServiceName = "singleton";
},
"singleton",
ServiceLifetime.Singleton);
services.AddFactory<IMyService, TransientService, TransientOption>(x =>
{
x.ServiceName = "transient";
},
"transient",
ServiceLifetime.Transient);
services.AddFactory<IMyService, ScopedService, ScopedOption>(x =>
{
x.ServiceName = "scoped";
},
"scoped",
ServiceLifetime.Scoped);
services.AddFactory<IMyService, ScopedService2, ScopedOption>(x =>
{
x.ServiceName = "scoped2";
},
"scoped2",
ServiceLifetime.Scoped);
await services.AddFactoryAsync<IMyService, ScopedService3, BuiltScopedOptions, ScopedOption>(
x =>
{
x.ServiceName = "scoped3";
},
"scoped3"
);
await services.AddFactoryAsync<IMyService, ScopedService3, BuiltScopedOptions, ScopedOption>(
x =>
{
x.ServiceName = "scoped3_2";
},
"scoped3_2"
);
await services.AddFactoryAsync<IMyService, ScopedService4, BuiltScopedOptions, ScopedOption>(
x =>
{
x.ServiceName = "scoped4";
},
"scoped4"
);
and use them in this way
var serviceProvider = services.BuildServiceProvider().CreateScope().ServiceProvider;
var factory = serviceProvider.GetService<IFactory<IMyService>>()!;
var factory2 = serviceProvider.GetService<IFactory<IMyService>>()!;
var singletonFromFactory = factory.Create("singleton").Id;
var singletonFromFactory2 = factory2.Create("singleton").Id;
var transientFromFactory = factory.Create("transient").Id;
var transientFromFactory2 = factory2.Create("transient").Id;
var scopedFromFactory = factory.Create("scoped").Id;
var scopedFromFactory2 = factory2.Create("scoped").Id;
var scoped2FromFactory = factory.Create("scoped2").Id;
var scoped2FromFactory2 = factory2.Create("scoped2").Id;
var scoped3FromFactory = factory.Create("scoped3").Id;
var scoped3FromFactory2 = factory2.Create("scoped3").Id;
var scoped3_2FromFactory = factory.Create("scoped3_2").Id;
var scoped3_2FromFactory2 = factory2.Create("scoped3_2").Id;
var scoped4FromFactory = factory.Create("scoped4").Id;
var scoped4FromFactory2 = factory2.Create("scoped4").Id;
Assert.Equal(singletonFromFactory, singletonFromFactory2);
Assert.NotEqual(transientFromFactory, transientFromFactory2);
Assert.Equal(scopedFromFactory, scopedFromFactory2);
Assert.Equal(scoped2FromFactory, scoped2FromFactory2);
Assert.NotEqual(scoped3FromFactory, scoped3FromFactory2);
Assert.NotEqual(scoped3_2FromFactory, scoped3_2FromFactory2);
Assert.NotEqual(scoped4FromFactory, scoped4FromFactory2);
Decorator
You may add a decoration for your services, based on the abstract factory integration. The decorator service replaces the previous version and receives it during the injection.
Setup
services
.AddService<ITestWithoutFactoryService, TestWithoutFactoryService>(lifetime);
services
.AddDecoration<ITestWithoutFactoryService, TestWithoutFactoryServiceDecorator>(null, lifetime);
Usage
var decorator = provider.GetRequiredService<ITestWithoutFactoryService>();
var previousService = provider.GetRequiredService<IDecoratedService<ITestWithoutFactoryService>>();
In decorator you may find the previousService in the method SetDecoratedService which runs in injection
public class TestWithoutFactoryServiceDecorator : ITestWithoutFactoryService, IDecoratorService<ITestWithoutFactoryService>
{
public string Id { get; } = Guid.NewGuid().ToString();
public ITestWithoutFactoryService Test { get; private set; }
public void SetDecoratedService(ITestWithoutFactoryService service)
{
Test = service;
}
public void SetFactoryName(string name)
{
return;
}
}
Decorator with Abstract Factory integration
You may add a decoration only for one service of your factory integration.
Setup
services.AddFactory<ITestService, TestService, TestOptions>(x =>
{
x.ClassicName = classicName;
},
factoryName,
lifetime);
services
.AddDecoration<ITestService, DecoratorTestService>(factoryName, lifetime);
Usage
var decoratorFactory = provider.GetRequiredService<IFactory<ITestService>>();
var decorator = decoratorFactory.Create(factoryName);
var previousService = decoratorFactory.CreateWithoutDecoration(factoryName);
Factory Fallback
You may add a fallback for your factory integration. The fallback service is called when the factory service key is not found.
services.AddFactoryFallback<TService, TFactoryFallback>();
where TFactoryFallback is class and an IFactoryFallback<TService>
You may add a fallback with an action fallback too.
services.AddActionAsFallbackWithServiceProvider<TService>(Func<FallbackBuilderForServiceProvider, TService> fallbackBuilder);
Scan dependency injection
You may scan your assemblies in search of types you need to add to dependency injection. For instance I have an interface IAnything and I need to add all classes which implements it.
public interface IAnything
{
}
internal class ScanModels : IAnything
{
}
and in service collection I can add it.
serviceCollection
.Scan<IAnything>(ServiceLifetime.Scoped, typeof(IAnything).Assembly);
I can add to my class the interface IScannable of T to scan automatically. For instance.
public interface IAnything
{
}
internal class ScanModels : IAnything, IScannable<IAnything>
{
}
and in service collection I could add it in this way
serviceCollection
.Scan(ServiceLifetime.Scoped, typeof(IAnything).Assembly);
Furthermore with ISingletonScannable, IScopedScannable and ITransientScannable I can override the service lifetime. For instance.
public interface IAnything
{
}
internal class ScanModels : IAnything, IScannable<IAnything>, ISingletonScannable
{
}
serviceCollection
.Scan(ServiceLifetime.Scoped, typeof(IAnything).Assembly);
ScanModels will be installed as a Singleton service, overwriting the service lifetime from Scan method.
You also automatically use different assembly sources.
serviceCollection
.ScanDependencyContext(ServiceLifetime.Scoped);
or
serviceCollection
.ScanCallingAssembly(ServiceLifetime.Scoped);
or
serviceCollection
.ScanCurrentDomain(ServiceLifetime.Scoped);
or
serviceCollection
.ScanEntryAssembly(ServiceLifetime.Scoped);
or
serviceCollection
.ScanExecutingAssembly(ServiceLifetime.Scoped);
or
serviceCollection
.ScanFromType<T>(ServiceLifetime.Scoped);
or
serviceCollection
.ScanFromTypes<T1, T2>(ServiceLifetime.Scoped);
Finally with ScanWithReferences you may call all the assemblies you want plus all referenced assemblies by them.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. |
-
net9.0
- Microsoft.Extensions.DependencyInjection (>= 9.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.0)
- Microsoft.Extensions.DependencyModel (>= 9.0.0)
- Rystem (>= 9.0.3)
NuGet packages (8)
Showing the top 5 NuGet packages that depend on Rystem.DependencyInjection:
Package | Downloads |
---|---|
Rystem.RepositoryFramework.Abstractions
Rystem.RepositoryFramework allows you to use correctly concepts like repository pattern, CQRS and DDD. You have interfaces for your domains, auto-generated api, auto-generated HttpClient to simplify connection "api to front-end", a functionality for auto-population in memory of your models, a functionality to simulate exceptions and waiting time from external sources to improve your implementation/business test and load test. |
|
Rystem.OpenAi
.Net wrapper for OpenAI with Dependency injection integration, factory integration: you may inject more than one endpoint, azure integration: you may swap among openai endpoint and any azure endpoint quickly and easily. You can calculate tokens and cost for each request (before the request) and for each response. You can access to the dashboard api to retrieve your current or previous billing. |
|
Rystem.Api
Rystem.Api helps you to integrate Api Server and Automated Client for Aspect-Oriented programming. |
|
Rystem.Content.Abstractions
Rystem.Content helps you to integrate with azure services or to create an abstraction layer among your infrastructure and your business. |
|
Rystem.Authentication.Social
Rystem.Authentication.Social helps you to integrate with new .Net Identity system and social logins. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
9.0.3 | 0 | 12/22/2024 |
9.0.2 | 62 | 12/21/2024 |
9.0.1 | 587 | 12/21/2024 |
9.0.0 | 173,741 | 11/16/2024 |
9.0.0-rc.1 | 231 | 10/18/2024 |
6.2.0 | 219,631 | 10/9/2024 |
6.1.2 | 94 | 10/9/2024 |
6.1.1 | 394 | 10/9/2024 |
6.1.0 | 48,266 | 9/29/2024 |
6.0.24 | 639 | 9/11/2024 |
6.0.23 | 340,549 | 7/18/2024 |
6.0.22 | 95 | 7/18/2024 |
6.0.21 | 488 | 6/18/2024 |
6.0.20 | 728,106 | 6/16/2024 |
6.0.19 | 31,038 | 6/14/2024 |
6.0.18 | 450 | 6/14/2024 |
6.0.17 | 461 | 6/14/2024 |
6.0.16 | 50,325 | 6/10/2024 |
6.0.15 | 454 | 6/9/2024 |
6.0.14 | 94,788 | 5/24/2024 |
6.0.13 | 461 | 5/23/2024 |
6.0.12 | 378 | 5/23/2024 |
6.0.11 | 472 | 5/20/2024 |
6.0.9 | 489 | 5/19/2024 |
6.0.7 | 437 | 5/18/2024 |
6.0.6 | 427 | 5/10/2024 |
6.0.5 | 374 | 5/10/2024 |
6.0.4 | 550,451 | 4/3/2024 |
6.0.3 | 1,869 | 3/25/2024 |
6.0.2 | 380,557 | 3/11/2024 |
6.0.1 | 51,114 | 3/8/2024 |
6.0.0 | 1,171,784 | 11/21/2023 |
6.0.0-rc.6 | 195 | 10/25/2023 |
6.0.0-rc.5 | 126 | 10/25/2023 |
6.0.0-rc.4 | 108 | 10/23/2023 |
6.0.0-rc.3 | 103 | 10/19/2023 |
6.0.0-rc.2 | 177 | 10/18/2023 |
6.0.0-rc.1 | 197 | 10/16/2023 |
5.0.20 | 640,241 | 9/25/2023 |
5.0.19 | 2,868 | 9/10/2023 |
5.0.18 | 2,144 | 9/6/2023 |
5.0.17 | 2,027 | 9/6/2023 |
5.0.16 | 2,064 | 9/5/2023 |
5.0.15 | 2,033 | 9/5/2023 |
5.0.14 | 2,043 | 9/5/2023 |
5.0.13 | 2,144 | 9/1/2023 |
5.0.12 | 1,991 | 8/31/2023 |
5.0.11 | 2,002 | 8/30/2023 |
5.0.10 | 2,045 | 8/29/2023 |
5.0.9 | 2,088 | 8/24/2023 |
5.0.8 | 2,089 | 8/24/2023 |
5.0.7 | 451,552 | 8/23/2023 |