[英]Dependency Injection and Configurations - .NET Core
创建一个读取 JSON 的独立项目并简单地回复。 试图充分利用依赖注入。 但是,我有几个问题需要澄清。
所以首先调用了依赖于ClassA
的HomeController
,因此在重构ClassA
实现IClassA
并更新Startup.cs
之后, HomeController
现在可以成功地使用 Startup.cs 创建的实例来调用方法_IClassA.GetOP(data)
。
现在我看到ClassA
依赖于ClassB
、 UtiClass
和Document
class 的类似行为。 所以我需要为所有人创建接口以删除用于创建实例的new
关键字。
同样,我的主要重点是检索KeysAndValues
-> path
的值。 因此,在ClassA
构造函数中,我实例化了ClassB
并传递了IOptions<KeyAndValue>
。 不幸的是,我无法获得options.path
的值。 请帮助澄清我的疑问并解决这个难题。 谢谢你。
//HomeController
public class HomeController : ControllerBase
{
private readonly IClassA _IClassA;
public HomeController(IClassA iClassA)
_IClassA = iClassA;
public string Get(DTO_A data)
var result = _IClassA.GetOP(data);
}
//INTERFACE
public interface IClassA
public string GetOP(DTO_A data);
//Class
public sealed class ClassA : IClassA
//private readonly IClassB _IClassB; //Cannot Instantiated
private readonly ClassB _ClassB;
public ClassA(IOptions<KeysAndValues> options)
_ClassB = new ClassB(options);
Document request = new Document();
UtiClass objUtiClass = new UtiClass();
public string GetOP(DTO_A data)
{
request.Name = data.Name;
objUtiClass .Document = request;
_ClassB.UpdateMethod(objUtiClass );
}
public class Document : IDocument
{}
public class ClassC
{}
启动.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IClassA, ClassA>();
services.AddControllers();
services.AddScoped<IClassB, ClassB>();
services.Configure<KeysAndValues>(Configuration.GetSection("KeysAndValues"));
}
public class ClassB : IClassB
private IOptions<KeysAndValues> options;
public ClassB(IOptions<KeysAndValues> options)
this.options = options;
public void UpdateMethod(UtiClass req)
string fille = Path.Combine(options.path);
}
public class KeysAndValues
public string path { get; set; }
就像 class HomeController
需要接口IClassA
, class ClassA
需要接口IClassB
。 Class ClassB
是需要IOptions<KeysAndValues>
的,因为实际上需要path
值的是ClassB
。
现在,您根本不需要在这里使用接口。 但是,我建议使用接口,因为如果您添加单元测试,它会让您的生活更轻松。
这是接口的样子。
public class HomeController : ControllerBase
{
private readonly IClassA _IClassA;
public HomeController(IClassA iClassA)
{
_IClassA = iClassA;
}
}
public interface IClassA { }
public interface IClassB { }
public class ClassA : IClassA
{
private readonly IClassB _IClassB;
public ClassA(IClassB iClassB)
{
_IClassB = iClassB;
}
}
public class ClassB : IClassB
{
private readonly KeysAndValues options;
public ClassB(IOptions<KeysAndValues> options)
{
this.options = options.Value;
}
}
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddTransient<IClassA, ClassA>();
services.AddTransient<IClassB, ClassB>();
services.Configure<KeysAndValues>(Configuration.GetSection("KeysAndValues"));
}
如果您不想使用接口,只需删除所有接口并将所有构造函数参数替换为具体的 class,并将ConfigureServices
修改为
services.AddTransient<ClassA>();
services.AddTransient<ClassB>();
我会推荐AddTransient
而不是AddScoped
。 仅当您需要来自该服务中明确的 HTTP 请求/响应的信息时,才使用 Scoped。 我还建议不要在服务( Document request
和UtiClass objUtiClass
)中包含任何不是readonly
且由 DI 设置的属性,否则您将需要使用AddSingleton
并确保您不会遇到竞争条件(您当前的代码看起来会的)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.