C# 在ConfigureServices-AddScoped期间使用注入的类实现选项模式
我有一个小班,在我的几个MVC应用程序上获取关于我的用户的一系列信息。一个最小的可复制示例是:C# 在ConfigureServices-AddScoped期间使用注入的类实现选项模式,c#,.net,design-patterns,dependency-injection,C#,.net,Design Patterns,Dependency Injection,我有一个小班,在我的几个MVC应用程序上获取关于我的用户的一系列信息。一个最小的可复制示例是: 公共类信息获取程序 { 公共字符串GetUserInformation(字符串连接str、字符串存储过程名称、int userId) { //SQL工作吗 退货信息; } } 我在ConfigureServices步骤中使用 services.AddScoped 然后在我的课堂上,我简单地从DI中调用它 现在,显然connectionStr和storedProcedure只在每个应用程序中更改,但
公共类信息获取程序
{
公共字符串GetUserInformation(字符串连接str、字符串存储过程名称、int userId)
{
//SQL工作吗
退货信息;
}
}
我在ConfigureServices步骤中使用
services.AddScoped
然后在我的课堂上,我简单地从DI中调用它
现在,显然connectionStr和storedProcedure只在每个应用程序中更改,但现在我将其作为参数传递
我尝试将这些参数公开,并使用服务进行配置。配置,但当我从控制器调用它时,会得到空值
services.AddOptions();
配置(选项=>
{
options.ConnectionString=Configuration.GetSection(“Model”).GetSection(“ConnectionString”).Value;
options.StoredProcedureName=“prInformationGetter”;
});
我不确定这失败的原因是因为我在我的原始类中缺少一个接口,还是我没有理解这个概念
我还考虑过做一些类似于services.AddInformationGetter(options=>{})
的事情,但我的理解是,这种模式是为了实现中间件,而不是专门用于DI
我试图查看文档(docs.microsoft.com),但我更加困惑。可能对涉及的概念有误解
Configure
将注册IOptions
。在您的示例中,现在有两个独立的注册
当你注册课程的时候
services.AddScoped<InformationGetter>()
InformationGetter
看起来像一个服务
我建议重构遵循更单一的责任原则(SRP)和关注点分离(Soc)设计
我将完全避免选项模式,只使用委托工厂注册类,从配置中提取我需要的内容。这样,您的代码就不会与诸如IOptions
public void ConfigureServices(IServiceCollection services) {
//...
InformationGetterOptions options = new InformationGetterOptions {
ConnectionString = Configuration.GetSection("Model").GetSection("ConnectionString").Value;
StoredProcedureName = "prInformationGetter";
};
services.AddSingleton(options);
services.AddScoped<IInformationGetter, InformationGetter>();
//...
}
public void配置服务(IServiceCollection服务){
//...
InformationGetterOptions选项=新的InformationGetterOptions{
ConnectionString=Configuration.GetSection(“Model”).GetSection(“ConnectionString”).Value;
StoredProcedureName=“prInformationGetter”;
};
服务。AddSingleton(选项);
services.addScope();
//...
}
现在,
IInformationGetter
可以在需要的地方注入,并具有执行其功能所需的所有依赖项。因此,如果Configure已经注册了该类,我还需要执行AddScoped吗?或者不需要执行AddScoped吗?Configure注册一个封装该类的IOptions。我会完全避免选项,只是使用委托工厂注册类,从配置中提取我需要的内容。您是否也可以使用您的建议进行更新?我正在学习,所以看到所有选项之间的差异将帮助我更好地理解我在做什么。@narsher check update。任何额外的事情都必须在一个新问题中完成,因为它将偏离问题的原始范围。非常感谢您的更新和建议。这让我的学习之旅变得更好:)
public class InformationGetter {
public string ConnectionString { get; set; }
public string StoredProcedureName { get; set; }
//...
public string GetUserInformation(int userId) {
// Do SQL work
return info;
}
}
//Needed by InformationGetter to perform its function
public class InformationGetterOptions {
public string ConnectionString { get; set; }
public string StoredProcedureName { get; set; }
}
//abstraction of InformationGetter
public interface IInformationGetter {
string GetUserInformation(int userId);
}
//implementation.
public class InformationGetter : IInformationGetter{
private readonly InformationGetterOptions options;
public InformationGetter(InformationGetterOptions options) {
this.options = options;
}
public string GetUserInformation(int userId) {
//use values in options to connect
// Do SQL work
return info;
}
}
public void ConfigureServices(IServiceCollection services) {
//...
InformationGetterOptions options = new InformationGetterOptions {
ConnectionString = Configuration.GetSection("Model").GetSection("ConnectionString").Value;
StoredProcedureName = "prInformationGetter";
};
services.AddSingleton(options);
services.AddScoped<IInformationGetter, InformationGetter>();
//...
}