.NET Core DI, register a default implementation for a package

Related searches

How can one register a default implementation using the IoC container for .NET Core and also provide a way to override the existing implementation ?

For example, I might want to create a package which provide a default implementation for some service.

namesapce Package 
{
    public interface ISomeService { }

    public class Default : ISomeService { }
}

This service is then used inside the same package.

namesapce Package 
{
    public class Service 
    {
        Service(ISomeService service) { }
    }
}

How to register the ISomeService default implementation?

Later when using this package in some project and want to override the existing implementation with another the Default should be replaced with Override.

namespace Project 
{
    public class Override : ISomeService { }
}

If your package contains a class that configures an IServiceCollection, such as this:

public class MyPackageInstaller
{
    public void Install(IServiceCollection services)
    {
        // Your package registers its services
    }
}

Then this can also be a point where you allow the consumer to make optional changes. For example, you could define a class like this which allows the consumer to specify implementations for certain services:

public class MyPackageRegistrationOptions
{
    public ServiceDescriptor FooServiceDescriptor { get; private set; }

    public void AddFooService(ServiceDescriptor fooDescriptor)
    {
        if (fooDescriptor.ServiceType != typeof(IFooService))
        {
            throw new ArgumentException("fooDescriptor must register type IFooService.");
        }
        FooServiceDescriptor = fooDescriptor;
    }
}

Now your installer can take those options, and register either the implementation specified by the consumer or its own default.

public class MyPackageInstaller
{
    private readonly MyPackageRegistrationOptions _options;

    public MyPackageInstaller(MyPackageRegistrationOptions options = null)
    {
        _options = options;
    }
    public void Install(IServiceCollection services)
    {
        if (_options?.FooServiceDescriptor != null)
            services.Add(_options.FooServiceDescriptor);
        else 
             // here's your default implementation
            services.AddSingleton<FooService>();
    }
}

Usage:

var services = new ServiceCollection();
var options = new MyPackageRegistrationOptions();
options.AddFooService(ServiceDescriptor.Singleton<IFooService, AlternateFooService>());
var installer = new MyPackageInstaller(options);
installer.Install(services);

At first glance it looks like a longer way to get the same result. The benefit is that it allows you to make it clearer which services should or should not be overridden. That way it feels more like you're working with deliberately exposed configuration options and less like poking at the internals of the package.

Instead of allowing the consumer to add a ServiceDescriptor you could allow them to specify only a service type, and your configuration determines how it gets registered (singleton, transient, etc.)

This is also a helpful pattern when the library depends on configuration values like connection strings which must be supplied by the consumer. You can make them required arguments to construct options and then require the options to construct the installer, or just make them required arguments in the installer. Now it's impossible to install the package without the needed configuration values.

Dependency injection in ASP.NET Core, NET Core supports the dependency injection (DI) software design pattern, which is a Registration of the dependency in a service container. extension method registers DbContext types with a scoped lifetime by default. How to inject multiple service class implementation of single interface in class using default asp.net core DI container 1 .NET Core DI, register a default implementation for a package

The built-in .NET Core DI Container allows an application developer to override registrations your package added to the ServiceCollection by simply appending the same service to the ServiceCollection. If multiple registrations are made for a single service type, the last registration will be used. For instance:

// Package registrations (part of your Package)
services.AddTransient<ISomeService, Default>();

// Override by application developer (part of his Startup.cs)
services.AddTransient<ISomeService, Override>();

DO CONSIDER to build your package in a way that it doesn't require the use of a DI Container, as described by Mark Seemann in his DI-Friendly Library article.

Essential .NET, NET Core dependency injection (DI) capabilities and how they enable an code to the object instantiated, along with a reference to its assembly/NuGet package. The solution is simply to first instantiate ServiceCollection's default constructor, then register the For example, the ILogger interface is defined in Microsoft. Dependency Injection in ASP.Net Core. Prior to .Net Core, the only way to get DI in your applications was through the use of a framework such as Autofac, Ninject, StructureMap and many others. However, DI is treated as a first-class citizen in ASP.Net Core. You can configure your container in your Startup.ConfigureServices method:

You can register whatever service you want inside your package and expose them via interfaces. Then when you will use it into some project, all you have to do to override the default package implementation is to override one of the exposed interfaces and that is that .

How to register a service with multiple interfaces in ASP.NET Core DI, NET Core DI container, and how to avoid a common bug. Registering a single implementation as multiple services Autofac uses this behaviour by default - the previous test would have passed NET Core in Action (6) C# (6) Git (6) Kubernetes (6) Middleware Analysis Package (6) Cake (5) Error� .NET Core uses dependency injection (DI) intensively, and thus a dependency injection framework is part of its core with Microsoft.Extensions.DependencyInjection. Configuration with .NET Core goes new ways to read configuration information from any configured source, such as JSON, XML, or environmental variables.

Using Scrutor to automatically register your services with the ASP , NET Core DI container; Scrutor vs third-party DI containers; Assembly scanning with Scrutor. Selecting and filtering the implementations to register; Handling duplicate To install Scrutor, run dotnet add package Scrutor from the .NET This is the default behaviour if you don't specify a registration strategy. So I agree with you in this point. Moreover, using two DI frameworks is worse than creating custom factory abstraction. In the second case you have to add new package dependency (like Unity) but depending on a new factory interface is less evil here. The main idea of ASP.NET Core DI, I believe, is simplicity.

Registering a type as an interface and as self with ASP.NET Core , the default Microsoft.Extensions.DependencyInjection package in ASP.NET Core, we can now consume an ICustomerService in, for example� Dependency Injection. Some love it, some hate it. For some developers it might be an anti-pattern, unnecessary, other developers cannot think about building applications without it. I believe that there are use cases where Dependency Injection frameworks are a good choice. Therefore, I created a few videos about Dependency Injection on my YouTube channel. Anyway, […]

04 July 2017 Posted in ASP.NET, .NET Core, Dependency Injection This post will be short and sweet, albeit one that caused me a bit of a headache. I recently worked on an ASP.NET Core project and I wanted to take advantage of the built-in Dependency Injection service to inject various services to the controllers.

Comments
  • In your registration: docs.microsoft.com/en-us/dotnet/api/… ?
  • OP is asking to override the existing implementation later on when needed. With the solution you have suggested, only Override will be available as the default implementation of ISomeService
  • @ShahzadHassan: The way I interpret OP's question, the replacement of Default is exactly what he wants.
  • Which means that Default will never be used, so what's the point of registering the Default?
  • @ShahzadHassan: The first registration is made by the package, the second registration is optionally made by the application developer that is using the package, but only in case he wants to replace Default.