AutoIoc 1.5.0
dotnet add package AutoIoc --version 1.5.0
NuGet\Install-Package AutoIoc -Version 1.5.0
<PackageReference Include="AutoIoc" Version="1.5.0" />
paket add AutoIoc --version 1.5.0
#r "nuget: AutoIoc, 1.5.0"
// Install AutoIoc as a Cake Addin #addin nuget:?package=AutoIoc&version=1.5.0 // Install AutoIoc as a Cake Tool #tool nuget:?package=AutoIoc&version=1.5.0
AutoIoc
Are you familiar with adding services, options/configurations from app settings, and HTTP client classes to your dependency injection container? Examples of what I mean:
services.AddTransient<IFooBarService, FooBarService>();
services.AddOptions<HelloWorldConfiguration>()
.Configure<IConfiguration>((settings, config) => { config.GetSection("HelloWorld").Bind(settings); });
services.AddTransient<AuthDelegatingHandler>();
services.AddHttpClient<IAnimeClient, AnimeClient>()
.AddHttpMessageHandler<AuthDelegatingHandler>();
services.AddRefitClient<IColorClient>()
.ConfigureHttpClient(c => {...})
.AddHttpMessageHandler<AuthDelegatingHandler>();
Then your code eventually grows to look like:
services.AddSingleton<IService1, Service1>()
.AddSingleton<IService2, Service2>()
.AddSingleton<IService3, Service3>()
/* pretend there are 100s of these */
.AddSingleton<IService99, Service99>()
.AddSingleton<IService100, Service100>();
Well this package makes that much easier. It will scan your assembly and fine items that need to be added to your DI container based on attributes.
NuGet Installation
Install the AutoIoc NuGet package:
dotnet add package AutoIoc
Usage
Add the following to your Startup.cs
:
services.AddAutoIoc(configuration, assembly);
Services
Add services based on the lifetime you'd like to have them have:
public interface IExample {}
Transient lifetime:
// always add it to the concrete class as that is where your behavior lives [TransientService] public class Example : IExample {} // this is equivalent to services.AddTransient<IExample, Example>();
Scoped lifetime:
// always add it to the concrete class as that is where your behavior lives [ScopedService] public class Example : IExample {} // this is equivalent to services.AddScoped<IExample, Example>();
Singleton lifetime:
// always add it to the concrete class as that is where your behavior lives [SingletonService] public class Example : IExample {} // this is equivalent to services.AddSingleton<IExample, Example>();
Options
Create your POCO class and add the following attribute with the desired app settings key:
// This will automatically bind the the key `Example`
[BindOptions]
public class ExampleConfiguration
{
public string Foo { get; set; }
public string Bar { get; set; }
}
// This will bind the the key `Foo:Bar`
[BindOptions("Foo:Bar")]
public class ExampleConfiguration
{
public string Foo { get; set; }
public string Bar { get; set; }
}
// now inject where desired
public class BananaService
{
private readonly ExampleConfiguration _exampleConfiguration;
public BananaService(IOptions<ExampleConfiguration> exampleConfigurationOptions)
{
_exampleConfiguration = exampleConfigurationOptions.Value;
}
}
HTTP Client Class
Typical Route
Normally I see developer creating a client class that injects a name HTTP client from the factory like as follows:
public interface IDbzClient{}
public class DbzClient : IDbzClient
{
private readonly HttpClient _httpClient;
public DbzClient(HttpClient httpClient)
{
_httpClient = httpClient;
}
}
// add to your DI container
services.AddHttpClient<IDbzClient, DbzClient>();
Why not just attribute it?
public interface IDbzClient {}
// always add it to the implementation since this is where your behavior lives
[HttpClient]
public class DbzClient : IDbzClient {}
Refit Route
Love using Refit? Me too! Go ahead and add one extra attribute to your interface so you won't need to add another line
to your Startup.cs
:
[HttpClient]
public class IDbzClient
{
[Get("/foo/bar")]
Task<ApiResponse<string>> GetFooBarAsync();
}
// now inject where desired
public class BananaService
{
private readonly IDbzClient _dbzClient;
public BananaService(IDbzClient dbzClient)
{
_dbzClient = dbzClient;
}
public async void CallItAsync()
{
var result = await _dbzClient.GetFooBarAsync();
if(result.IsSuccessStatusCode)
{
Console.WriteLine(result.Content);
}
}
}
Prerequisites
This will look for the BaseAddress
and TimeoutSeconds
(OPTIONAL) keys in your appsettings under the default parent key of your client's name minus the *Client
postfix. For example, if your client's interface is IGoosfrabaClient
, then next your settings as follows:
{
"Goosfraba": {
"BaseAddress": "https://goosfraba.com",
"TimeoutSeconds": 100
}
}
Delegating Handlers
Need to add delegating handlers? Well this is how you used to do it:
public class AuthDelegatingHandler : DelegatingHandler { }
services.AddTransient<AuthDelegatingHandler>();
services.AddHttpClient<IExampleClient, ExampleClient>()
.AddHttpMessageHandler<AuthDelegatingHandler>();
Now you can add as many as you want via attributes:
public class AuthDelegatingHandler : DelegatingHandler { }
// examples and order matters
[HttpClient(PrimaryHandler = typeof(CustomPrimaryHandler))]
[HttpClient(typeof(AuthDelegatingHandler), PrimaryHandler = typeof(CustomPrimaryHandler))]
[HttpClient(typeof(AuthDelegatingHandler), typeof(RandomDelegatingHandler), PrimaryHandler = typeof(CustomPrimaryHandler))]
[HttpClient(typeof(AuthDelegatingHandler))]
[HttpClient(typeof(AuthDelegatingHandler), typeof(RandomDelegatingHandler))]
Ping me if you want any new features added to the library ❤️
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net8.0
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Http (>= 8.0.1)
- Microsoft.Extensions.Options (>= 8.0.2)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
- Refit (>= 8.0.0)
- Refit.HttpClientFactory (>= 8.0.0)
- ThrowIfArgument (>= 1.1.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.5.0 | 325 | 11/7/2024 |
1.5.0-beta | 72 | 11/7/2024 |
1.4.0 | 1,998 | 5/29/2024 |
1.3.0 | 15,821 | 12/12/2022 |
1.2.1-beta01 | 147 | 12/12/2022 |
1.2.0 | 289 | 12/9/2022 |
1.1.0 | 310 | 12/9/2022 |
1.0.1 | 308 | 12/9/2022 |
1.0.0 | 311 | 12/7/2022 |
0.0.0-alpha01 | 157 | 12/7/2022 |
Upgrading NuGet packages due to security issue found in ReFit library