我遇到了.Net Core
,我正面临着它的DI引擎。
我的项目是一个类库,因此,asp的绑定在这里无关紧要。
我按照this article的提示进行DI工作。
我已经建立了一个如下所示的服务提供商:
public static class ServiceProvider
{
public static IServiceProvider GetServiceProvider()
{
var services = new ServiceCollection();
//Singletons
services.AddSingleton<IInstance, Instance>();
//Transients
services.AddTransient<IDate, Date>();
services.AddTransient<IMath, Math>();
services.AddTransient<INumber, Number>();
return services.BuildServiceProvider();
}
}
然后我尝试在一个看起来像这样的静态类中执行它:
public static class MySingleton
{
public static IInstance Instance
=> ServiceProvider.GetServiceProvider().GetService<IInstance>();
}
并且为了测试单例行为,我测试了它:
[Test]
public void Instance_HundredTimes_ReturnsSameInstance()
{
//Arrange
const int callCount = 100;
var results = new IInstance[callCount];
//Act
for (var i = 0; i < callCount; i++)
{
results[i] = MySingleton.Instance;
}
//Assert
Assert.That(results.Distinct().Count(), Is.EqualTo(1));
}
测试结果显示为负数,而不是在distinct之后有一个引用(因为它是一个单例),我仍然留下了一百个实例。
我做错了吗?我在配置中遗漏了什么吗?
答案 0 :(得分:2)
您的问题出在此代码块中:
public static class MySingleton
{
public static IInstance Instance
=> ServiceProvider.GetServiceProvider().GetService<IInstance>();
}
您在这里所做的是每次访问该物业时都致电ServiceProvider.GetServiceProvider().GetService<IInstance>()
。这意味着实际上没有单身人士。你想要做的是设置一次单例实例:
public static class MySingleton
{
public static IInstance Instance
{
get;
} = ServiceProvider.GetServiceProvider().GetService<IInstance>();
}
此外,您在创建服务时遇到类似问题。每次致电ServiceCollection
时,您都会创建一个新的GetServiceProvider()
。你可能不想要那个。你可能想要这样的东西:
public static class ServiceProvider
{
private static IServiceProvider serviceProvider = null;
public static IServiceProvider GetServiceProvider()
{
if (serviceProvider == null)
{
var services = new ServiceCollection();
//Singletons
services.AddSingleton<IInstance, Instance>();
//Transients
services.AddTransient<IDate, Date>();
services.AddTransient<IMath, Math>();
services.AddTransient<INumber, Number>();
serviceProvider = services.BuildServiceProvider();
}
return serviceProvider;
}
}
答案 1 :(得分:0)
我的问题在于不将我的IserviceProvider
实例保留在MySingleton
<强> TL; DR 强>
有一个IserviceProvider
代码重构
重构ServiceProvider
看起来如下:
公共类LodashServiceProvider { private static readonly Lazy LazyServiceProvider;
static LodashServiceProvider()
{
LazyServiceProvider = new Lazy<IServiceProvider>(InitializeServiceProvider);
}
public static IServiceProvider GetServiceProvider() => LazyServiceProvider.Value;
private static IServiceProvider InitializeServiceProvider()
{
var services = new ServiceCollection();
//Singletons
services.AddSingleton<ILodashInstance, LodashInstance>();
//Transients
services.AddTransient<ILodashDate, LodashDate>();
services.AddTransient<ILodashMath, LodashMath>();
services.AddTransient<ILodashNumber, LodashNumber>();
return services.BuildServiceProvider();
}
}