c# - ASP.NET 核心 DI : Resolve same instance if scoped service is registered both as service type and implementation type

标签 c# dependency-injection asp.net-core

假设我有一个服务,我想在限定的生命周期内解决。但有时我尝试将其解析为接口(interface)类型,有时是实现类型。

我尝试做的第一件事是:

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

上述示例的问题在于,如果我解析 IMyInterface 而不是解析 MyClass,则会使用不同的实例。基本上 2 个作用域实例可能同时存在。

我通过以下方式解决了这个问题。但它非常容易出错,因为您很容易忘记在一个地方执行此操作,而且很难注意到。

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

有什么方法可以以不易出错的方式完成我想要的事情。最好(但不一定)在一次注册中?

即作为 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 { }
}

最佳答案

一种选择是创建您自己的扩展方法,该方法包含您在问题中显示的两行。例如:

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>());
    }
}

你可以这样调用它:

serviceCollection.AddScopedInterfaceAndClass<IMyInterface, MyClass>();

我知道 AddScopedInterfaceAndClass 不是完美的名称 - 它只是一个演示该想法的示例。此外,还有一个缺点是您必须记住使用此扩展而不是AddScoped

注意:您可以通过删除第二个泛型 (TClass) 来简化扩展方法中的第二个 AddScoped,因为这是由编译器推断的。

关于c# - ASP.NET 核心 DI : Resolve same instance if scoped service is registered both as service type and implementation type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47677504/

相关文章:

c# - ILogger 接口(interface)未将所有内容记录到事件日志/核心 3.0

c# - 如何处理 3 层架构中的多条件查询

php - 为什么服务定位器是以下示例中的反模式?

c# - ChangeLog OriginalValue 与 EF Core 更新实体上的 CurrentValue 相同

angular - 如何使用工厂供应商?

c# - Entity Framework 4 DB-First 依赖注入(inject)?

c# - 模拟 SignInManager

c# - 检查 Entity Framework linq 结果中的项目

c# - Visual Studio 中的圈复杂度

c# - 获取 NullReferenceException