使用单例数据源的瞬态和作用域服务
Posted
技术标签:
【中文标题】使用单例数据源的瞬态和作用域服务【英文标题】:Transient and Scoped services consuming a singleton data source 【发布时间】:2021-04-28 08:52:34 【问题描述】:我正在尝试学习依赖倒置和 IOC。在这个过程中,我碰壁了。
这就是我对 DI 原则的理解 -> 高级类基于抽象而不是实现。
一切都好。
因此请牢记上述内容。我有下面的例子。
public interface IServiceA
public void DoSomething();
public class ServiceA : IServiceAInterface
IDataInterface dataSource;
DataSourceType data;
// omitted config injectino for brevity
public ServiceA(IDataInterface _data)
dataSource = _dataSource;
var dataSourceName = config.GetValue<string>("DataSourceName");
data = dataSource.GetDataSource(dataSourceName);
public void doSomething()
data.doSomething();
public interface IDataInterface
public DataSourceType getDataSource(string ds);
public class DataAccessService : IDataInterface
public DataSourceType GetDataSource(string dataSource)
if (dataSource == "InApp")
var source = new DataSourceType();
return source;
else
return null;
上面是一个服务类,它需要数据来执行它从DataAccessService
获取的任务。
现在我正在使用应用程序类/模型在整个应用程序生命周期中保持持久性。因此我将其注册为单例。
Startup.cs
public void ConfigureServices(IServiceCollection services)
---
services.AddSingelton<IDataInterface,DataAccessService>();
service.AddScoped<IServieAInterface,ServiceA>();
---
这不起作用。
我假设这是因为父服务(服务 A)的生命周期比子服务(DataAccessService
)的生命周期短。
我由此了解到服务 A 负责对象的实例化。
但是,我希望 IOC 容器仅实例化一个 DataAccessService
对象并将其注入所有需要此对象的服务。
不知道为什么我的假设是错误的。
基于上述假设,我尝试了以下方法:
public interface IDataInterface
public class DataAccessService : IDataInterface
public DataSourceType dataSource;
public DataAccessService(string ds)
if (ds == "InApp")
this.dataSource = new DataSourceType();
else
this.dataSource = null;
public class ServiceA: DataAccessService,IServceAInterface
DatSourceTye data;
public ServiceA():base("InApp")
config = _config;
data = dataSource;
public void doSomething()
data.doSomething();
Startup.cs
// Hoping to pass parameter through startup
services.AddSingleton<IDataInterface>(x =>
ActivatorUtilities.CreateInstance<DataAccessService>(x, "InApp")
);
service.AddScoped<IServieAInterface,ServiceA>();
我希望上面的方法可以工作,因为这里DataAccessService
负责初始化。
但仍然会为每个类创建一个新的 DataAccessService
对象。
我想,我搞砸了我对生命周期如何运作的理解。 在这方面需要帮助。
另外,我想要实现的是一个单一的数据源,不同的服务在整个应用程序生命周期中都在作用于它。
使用单例数据源的瞬态和范围服务。我认为这应该是可能的
我想要实现的设计在设计方面有什么不好的地方吗?
【问题讨论】:
完全有可能,您需要明确了解实际发生的情况。 Transient 和 Scoped 可以使用单例服务,但反之则不行。这不仅有可能,而且非常普遍。请edit 这个并附上minimal reproducible example。 如果加上错误信息就好了.. 没有收到任何错误,每次请求都会获取一个新实例。让我用更多代码编辑问题:) 在这里,我将 DataAccessService 注册为 Singelton 类,其余为 Transient,但 ApplicationDataSource 类在每个请求中都不断被重新实例化,因此我在每个请求中都获得了新对象。然而,让一切都很好。 发现我的错误,问题是 -> 我正在使用数据服务来获取数据源的实例。该服务是构造函数注入的。但是,为了从服务中获取数据源,我实际上是在其中一种服务方法中手动实例化数据源类。因此,尽管该服务是单例的,但每次我调用它的 GetDataSource 方法时,都会给我一个新实例。将关闭问题,ty :) 【参考方案1】: public DataAccessService(string ds)
if (ds == "InApp")
this.dataSource = new DataSourceType();
else
this.dataSource = null;
数据服务中的这个方法每次都被调用,我需要数据源。 由于此方法是手动实例化另一个类,虽然服务是单例的, 每次调用上述方法 - DataAccessService 时,我都会得到一个新实例。
【讨论】:
以上是关于使用单例数据源的瞬态和作用域服务的主要内容,如果未能解决你的问题,请参考以下文章
数据未保存:对象引用了未保存的瞬态实例 - 在刷新之前保存瞬态实例 [重复]