繁体   English   中英

依赖注入和配置 - .NET 核心

[英]Dependency Injection and Configurations - .NET Core

创建一个读取 JSON 的独立项目并简单地回复。 试图充分利用依赖注入。 但是,我有几个问题需要澄清。

所以首先调用了依赖于ClassAHomeController ,因此在重构ClassA实现IClassA并更新Startup.cs之后, HomeController现在可以成功地使用 Startup.cs 创建的实例来调用方法_IClassA.GetOP(data)

现在我看到ClassA依赖于ClassBUtiClassDocument 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 requestUtiClass objUtiClass )中包含任何不是readonly且由 DI 设置的属性,否则您将需要使用AddSingleton并确保您不会遇到竞争条件(您当前的代码看起来会的)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM