请随意建议一个更好的问题标题。我无法想出一个好的名称来描述这个问题。
我需要通过依赖注入,使一个类在启动时可访问。该类不仅应该通过其具体实现而还可以通过它实现的接口进行访问。并且我需要确保两次注入返回的是同一个对象实例。
导致我使用单例模式的真实场景是一个抽象 nuget 提供了接口(IStore),多个 nuget 拥有具体实现(DBStore、RedisStore)。当我尝试为每个存储实现实现健康检查时,我可以获得 IStore 的注入,但不能获取具体实现的注入。而且我希望使用一些在具体实现中初始化和修改的变量(这就是为什么我需要两次注入返回同一个实例)。由于这些存储(希望)作为单例使用,所以它们起作用。我并不是说对于范围和瞬态方式有一个真正的场景。我只是很好奇如果它们不是单例,是否可能。
以下代码描述了我如何使用单例解决这个问题。
导致我使用单例解决方法的原因:
有了这个接口:
那么我该如何在使用scoped或transient时,实现两次注入的是相同实例并使用相同设置呢?因为我认为我不能手动/编码创建实例。
我需要通过依赖注入,使一个类在启动时可访问。该类不仅应该通过其具体实现而还可以通过它实现的接口进行访问。并且我需要确保两次注入返回的是同一个对象实例。
导致我使用单例模式的真实场景是一个抽象 nuget 提供了接口(IStore),多个 nuget 拥有具体实现(DBStore、RedisStore)。当我尝试为每个存储实现实现健康检查时,我可以获得 IStore 的注入,但不能获取具体实现的注入。而且我希望使用一些在具体实现中初始化和修改的变量(这就是为什么我需要两次注入返回同一个实例)。由于这些存储(希望)作为单例使用,所以它们起作用。我并不是说对于范围和瞬态方式有一个真正的场景。我只是很好奇如果它们不是单例,是否可能。
以下代码描述了我如何使用单例解决这个问题。
导致我使用单例解决方法的原因:
有了这个接口:
public interface ITestInterface
{
string ReturnAString();
int ReturnAnInt();
}
以及这个具体的实现
public class TestImplementation : ITestInterface
{
private int counter = 0;
public string ReturnAString() {return "a string"; }
public int ReturnAnInt() { return counter++; }
}
它们被用于两个(假设)服务中。一个服务需要在构造函数中注入接口,而另一个服务需要具体实现。
在Startup.ConfigureServices方法中尝试多次,并使两种情况下注入相同的实例:
尝试1:
// only ITestInterface is injected but not TestImplemenation
services.AddSingleton<ITestInterface, TestImplementation>();
尝试二:
//only TestImplementation is injected (DI does not recognize it implements the Interface)
services.AddSingleton<TestImplementation>();
尝试 3:
// both are injected but they are not singleton any more (counters increment independently)
services.AddSingleton<ITestInterface, TestImplementation>();
services.AddSingleton<TestImplementation, TestImplementation>();
尝试4:
TestImplementation instance = new TestImplementation();
services.AddSingleton<ITestInterface>(instance);
services.AddSingleton(instance);
//services.AddSingleton<TestImplementation>(instance);
第四次尝试时,我为两种注入方式使用了相同的实例。
现在假设TestImplementation需要注入一些设置(例如连接)。
我可以编写一个扩展方法从配置中获取设置并将其传递给单例实例。
TestImplementation instance = new TestImplementation(Configuration.GetTestSettings());
services.AddSingleton<ITestInterface>(instance);
services.AddSingleton(instance);
那么我该如何在使用scoped或transient时,实现两次注入的是相同实例并使用相同设置呢?因为我认为我不能手动/编码创建实例。