Injectable.NetCore.Extensions
1.4.0
See the version list below for details.
dotnet add package Injectable.NetCore.Extensions --version 1.4.0
NuGet\Install-Package Injectable.NetCore.Extensions -Version 1.4.0
<PackageReference Include="Injectable.NetCore.Extensions" Version="1.4.0" />
paket add Injectable.NetCore.Extensions --version 1.4.0
#r "nuget: Injectable.NetCore.Extensions, 1.4.0"
// Install Injectable.NetCore.Extensions as a Cake Addin #addin nuget:?package=Injectable.NetCore.Extensions&version=1.4.0 // Install Injectable.NetCore.Extensions as a Cake Tool #tool nuget:?package=Injectable.NetCore.Extensions&version=1.4.0
Injectable.NetCore.Extensions
Injectable Extensions enable simple, convention-based injection for .Net Core and .Net Standard services.
Injectable Extensions streamlines dependency injection in .Net Core and .Net Standard development scenarios by providing a set of extensions methods which enable convention-based injection from loaded assemblies. The extensions can be used directly from any IServiceCollection, or a broader set of injection rules can be provided via the InjectionSettings class.
Installation
From Package Manager Console:
Install-Package Injectable.NetCore.Extensions
From Cli:
dotnet add package Injectable.NetCore.Extensions
Injection Scopes
Injectable Extensions supports three forms of injection scopes provided by the InjectionMode
enum:
namespace Injectable.NetCore.Extensions
{
public enum InjectionMode
{
Scoped,
Singleton,
Transient
}
}
InjectionSettings
This is the definition of the IInjectionSettings
interface. Any implementation of this interface can be passed into the InjectByConvention
method.
Property | Type | Default | Usage |
---|---|---|---|
InterfacePrefix | string | null | Prefix of interface types, defaults to "I" |
InterfaceSuffixList | List<string> | Interface suffixs to identify injectables | |
InterfaceRootNamespaces | List<string> | Namespaces to load interfaces from | |
EnforceStrictNaming | bool | true | When set to true, Injected classes must have the same name as the interface, without the leading prefix <br /><br />For Example: INameProvider will inject the NameProvider class, but not TheNameProvider, even if TheNameProvider implements INameProvider |
RestrictImplementationsToInterfaceNamespaces | bool | false | When set to true, only classes in the same root namespaces as the interface collections they implement will be injected |
AllowedImplementationNamespaces | List<string> | <p>Defines the list of namespaces where implementation of the interfaces is allowed for injection</p><p>An empty or null list will allow implementation in any namespace unless restricted by the RestrictImplementationsToInterfaceNamespaces property</p><p>Namespaces can be provided as the partially (ends with) or fully Qualified Namespace</p><p>For Example: To inject an implementation from MyAssembly.Utilities.Dates any of the following will work<br /><br />"MyAssembly.Utilities.Dates"<br />"Utilities.Dates"<br />"Dates"</p> | |
InjectionMode | InjectionMode | InjectionMode.Scoped | Specifies the injection mode from Injectable.NetCore.Extensions.InjectionMode |
ForceImplementationForAllDefinitions | bool | true | When true, thows an exception if any interface matching the convention is not implemented |
Method | Returns | Usage |
---|---|---|
Validate() | void | Checks settings for minimum viable usability, throws an InvalidOperationException if validation criteria fails |
Configure(bool forceImplementationForAllDefinitions = true) | IInjectionRootNamespaceConfiguration |
Begins Fluent Configuration |
Usage 1: Fluent Injection
There is a fluent method for configuring the IInjectionSettings
in the package that will guide you through the completion of valid settings.
If your interface declarations are:
namespace MyNamespace.ServiceContracts {
public interface IPersonService {}
public interface IAddressService {}
}
namespace MyUfoNamespace {
public interface IUfoService {}
}
By convention, your implementations are:
namespace MyOtherNamespace.Services {
public class PersonService: IPersonService {}
public class AddressService: IAddressService {}
public class UfoService: IUfoService {}
}
This method of injection will look similar to this:
public void ConfigureServices(IServiceCollection services){
var injectionSettings = InjectionSettings
.WithInjectionMode(InjectionMode.Scoped)
.WithRootNamespaces("MyNamespace", "MyUfoNamespace")
.AllowImplementationsInAnyNamespace()
.WithInterfacePrefix("I")
.WithInterfaceSuffix("Service")
.WithStrictNaming();
services.InjectByConvention(injectionSettings);
}
This will result in All Interfaces starting with "I" and ending in "Service" residing anywhere in the InjectionClasses or InjectionClasses2 namespaces with implementations whose class names match the interface names (without the prefix). Since multiple root namespaces were specified, all the implementations will be injected.
Usage 2: Explicit Scope Injection
Explicit extension methods exist for each type of scope by providing a root namespace and suffix. So if my convention for naming your service interfaces is "I<ClassName>Service" (we default the prefix to "I", but that can also be overriden)
If your interface declarations are:
namespace MyNamespace.ServiceContracts {
public interface IPersonService {}
public interface IAddressService {}
public interface IUfoService {}
}
By convention, your implementations are:
namespace MyOtherNamespace.Services {
public class PersonService: IPersonService {}
public class AddressService: IAddressService {}
public class UfoService: IUfoService {}
}
Then injecting those into your services is as easy as:
public void ConfigureServices (IServiceCollection services) {
// Transient injection
services.InjectTransientsFrom("MyNamespace", "Services");
// Scoped injection
services.InjectScopedFrom("MyNamespace", "Services");
// Singleton injection
services.InjectSingletonsFrom("MyNamespace", "Services");
}
There are many optional parameters to the Inject extenstions that allow you to customize the behavior which all roll up into an InjectionSettings instance before being passed into the InjectByConvention
method.
Reflection, Injection, and Multiple Implementations
I realize there is nothing that prevents or restricts the implementation of an interface on multiple classes. HOWEVER, there is a limitation on this imposed by the dependency injection process that does not allow multiple implementations for injected types. This will cause an error.
Change Log
Version | Changes |
---|---|
1.4.0.0 | Fixed a bug when using no suffix list, added xml documentation |
1.3.0.1 | <ul><li>Added type-based option for supplying fluent namespaces</li><li>Added Change Log to readme.md</li></ul> |
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Extensions.DependencyInjection (>= 5.0.1)
-
.NETStandard 2.1
- Microsoft.Extensions.DependencyInjection (>= 5.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Added type-based configuration to the fluent configuration paths