简体   繁体   English

ASP.NET Core DI:如果将作用域服务注册为服务类型和实现类型,则解析相同的实例

[英]ASP.NET Core DI: Resolve same instance if scoped service is registered both as service type and implementation type

Say I have a service that I want to resolve with a scoped lifetime. 假设我有一个我想用scoped生命周期来解决的服务。 But sometime I try to resolve it as the interface type and sometimes at the implementation type. 但有时我尝试将其解析为接口类型,有时在实现类型。

The first thing I tried to do was this: 我试图做的第一件事是:

ServiceCollection services;
services.AddScoped<MyClass>();
services.AddScoped<IMyInterface, MyClass>();

The problem with the above sample is that a different instance is used if I resolve IMyInterface, and than resolve MyClass. 上面的示例的问题是,如果我解析IMyInterface,则使用不同的实例,而不是解析MyClass。 Basically it's possible that 2 scoped instances are alife at the same time. 基本上,两个范围的实例可能同时存在。

I work around this issue in the following way. 我通过以下方式解决此问题。 But it's very error-prone because you can easily forget to do this at one place, and it's really hard to notice. 但它很容易出错,因为你很容易忘记在一个地方做这件事,而且很难注意到。

serviceCollection.AddScoped<MyClass>();
serviceCollection.AddScoped<IMyInterface, MyClass>(sp => sp.GetRequiredService<MyClass>());

Is there any way to accomplish what I want in a way that is less error prone. 有没有办法以一种不易出错的方式完成我想要的东西。 Preferrably, but not necessarily, in a single registration? 优先,但不一定,在一次注册?

Ie as an xUnit test: 即作为xUnit测试:

public class Tests
{
    [Fact]
    public void ReturnsSameInstanceForImplementationAndServiceType()
    {
        var serviceCollection = new ServiceCollection();

        // TODO: Change these lines so they're less error prone.
        serviceCollection.AddScoped<MyClass>();
        serviceCollection.AddScoped<IMyInterface, MyClass>(sp => sp.GetRequiredService<MyClass>());

        var services = serviceCollection.BuildServiceProvider();
        var myInt = services.GetRequiredService<IMyInterface>();
        var myCls = services.GetRequiredService<MyClass>();

        Assert.Equal(myCls, myInt);
    }

    class MyClass : IMyInterface { }
    interface IMyInterface { }
}

One option would be to create your own extension method that wraps up the two lines you've shown in your question. 一种选择是创建自己的扩展方法,将您在问题中显示的两条线包装起来。 For example: 例如:

public static class ServiceCollectionExtensions
{
    public static void AddScopedInterfaceAndClass<TInterface, TClass>(this IServiceCollection serviceCollection)
        where TInterface : class
        where TClass : class, TInterface
    {
        serviceCollection.AddScoped<TClass>();
        serviceCollection.AddScoped<TInterface, TClass>(sp => sp.GetRequiredService<TClass>());
    }
}

You could call this like so: 你可以这样称呼它:

serviceCollection.AddScopedInterfaceAndClass<IMyInterface, MyClass>();

I appreciate that AddScopedInterfaceAndClass isn't the perfect name - it's just an example to demonstrate the idea. 我很欣赏AddScopedInterfaceAndClass不是一个完美的名字 - 它只是一个展示这个想法的例子。 Also, there is still the downside that you'd have to remember to use this extension rather then AddScoped . 此外,还有一个缺点,你必须记住使用此扩展而不是AddScoped

Note: You could simplify the second AddScoped in the extension method by removing the second generic ( TClass ) as this is inferred by the compiler. 注意:您可以简化第二AddScoped通过移除第二通用(在扩展方法TClass ),因为这是由编译器推断。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ASP.NET 内核中的错误:没有注册类型 […] 的服务 - Error in ASP.NET Core : no service for type […] has been registered ASP.Net Core 2无法解析类型服务 - ASP.Net Core 2 Unable to resolve service for type Net Core 2控制台应用程序-DI&#39;无法解析类型的服务...&#39; - Net Core 2 Console App - DI 'Unable to resolve service for type…' 我的 .NET 7 应用无法解析某个类型的服务。 已经添加到 DI - My .NET 7 app is unable to resolve the service for a type. Already added scoped to DI ASP.NET Core:带条件的DI服务 - ASP.NET Core: DI Service with conditions ASP.NET 核心依赖注入错误 - 尝试激活“服务”时无法解析“存储库”类型的服务 - ASP.NET Core Dependency Injection error - Unable to resolve service for type “Repository” while attempting to activate “Service” ASP.NET 核心 3:InvalidOperationException:没有 Microsoft.AspNetCore.Mvc.Routing.ControllerActionEndpointDataSource 类型的服务已注册 - ASP.NET Core 3: InvalidOperationException: No service for type Microsoft.AspNetCore.Mvc.Routing.ControllerActionEndpointDataSource has been registered .net 核心中的范围服务 DI 和 GC - 澄清? - Scoped service DI & GC in .net CORE - Clarification? ASP.NET Core 2 无法解析 Microsoft EntityFrameworkCore DbContext 类型的服务 - ASP.NET Core 2 Unable to resolve service for type Microsoft EntityFrameworkCore DbContext ASP.NET Core 错误:尝试激活时无法解析类型服务 - ASP.NET Core error: Unable to resolve service for type while attempting to activate
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM