简体   繁体   中英

.NET Core DI without constructor arguments

Until now, I have used the Unity IOC container to resolve dependencies, which works just fine. With the Unity DI, I normally resolve instances in the following way:

Public class TestClass {
    public TestClass()
    {
        var instance = IOC.resolve<InterfaceClassToResolve>();
    }
}

This works great, but seeing that .net core now provides me with an out of the box DI container, I would much rather like to use that - There is just one problem compared to the Unity IOC, namely that it is injected as a constructor argument, and not resolved like the example above.

In most cases, I figured that it forces me to chain my dependencies throughout multiple classes, instead of just resolving my dependency in the classes that actually needs them.

I have been looking at ways to solve this, and as far as I can see, the only option is to do something like this:

Public class TestClass {
    public TestClass(IServiceProvider serviceProvider)
    {
        var instance = serviceProvider.GetService<InterfaceClassToResolve>();
    }
}

And then we are back to square one again...

Therefore, am I missing some of the functionality behind the .net core IOC, or is there some secret sauce to why most examples wants me use the .net core IOC via constructor arguments?

As already commented, Service Locator pattern is not the best method and considered an anti-pattern. I understand the necessity, though, of finding a way to easily convert existing code to the out-of-the-box DI system without going mad. I therefore suggest you to do something like this:

1) Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<DatabaseContext>(
            options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

        // other services configuration here

        // IMPORTANT: This should be the last line of ConfigureServices!
        IOC.CurrentProvider = services.BuildServiceProvider();
    }
...

2) IOC.cs

public class IOC
{
    public static IServiceProvider CurrentProvider { get; internal set; }

    public static T resolve<T>()
    {
        return CurrentProvider.GetService<T>();
    }
}

This should allow you to use dotnet core DI with existing service locator code based on Unity, with minimal fixes (basically just some using declarations to be fixed), as long as you solemnly promise to refactor your code as soon as possible to get rid of all that Service Locator code :D

You can use DI without constructors like:

On the ConfigureServices

services.AddSingleton<YourClass>()

Then inject it like this:

private YourClass YourClass
{
    get
    {
        return this.serviceProvider.GetRequiredService<YourClass>();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM