Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SRP、DI和app.config:何时实例化注入类?_C#_Dependency Injection_Configuration Files_Solid Principles_Single Responsibility Principle - Fatal编程技术网

C# SRP、DI和app.config:何时实例化注入类?

C# SRP、DI和app.config:何时实例化注入类?,c#,dependency-injection,configuration-files,solid-principles,single-responsibility-principle,C#,Dependency Injection,Configuration Files,Solid Principles,Single Responsibility Principle,我正在重构一个小型的报表生成应用程序,使其遵循可靠的原则,等等。因此,我所有的类都遵循带有DI的SRP,我使用app.config处理大多数参数变化。我还没有使用任何DI框架,而是在应用程序入口点创建所有依赖类。然而,这导致了一个设计问题,我在这里概括如下: 我可以像这样创建依赖项和主报告器类: //dependencies var sharedDependency = new SharedDependency(); var whiteColorDependency = new Col

我正在重构一个小型的报表生成应用程序,使其遵循可靠的原则,等等。因此,我所有的类都遵循带有DI的SRP,我使用app.config处理大多数参数变化。我还没有使用任何DI框架,而是在应用程序入口点创建所有依赖类。然而,这导致了一个设计问题,我在这里概括如下:

我可以像这样创建依赖项和主报告器类:

//dependencies    
var sharedDependency = new SharedDependency();

var whiteColorDependency = new ColorDependency("white");
var blueColorDependency = new ColorDependency("blue");

var config1Dependency = new MultiDependency("config1");
var config2Dependency = new MultiDependency("config2");
...
var config12Dependency = new MultiDependency("config12");



//main logic
var reporter1 = new Reporter(sharedDependency, whiteColorDependency, config1Dependency);
var reporter2 = new Reporter(sharedDependency, whiteColorDependency, config2Dependency);
var reporter3 = new Reporter(sharedDependency, whiteColorDependency, config3Dependency);
...
var reporter10 = new Reporter(sharedDependency, blueColorDependency, config10Dependency);
var reporter11 = new Reporter(sharedDependency, blueColorDependency, config11Dependency);
var reporter12 = new Reporter(sharedDependency, blueColorDependency, config12Dependency);
或者像这样:

foreach (var config in configs)
{
    //dependencies
    var sharedDependency = new SharedDependency();
    var colorDependency = new ColorDependency("color");
    var configDependency = new MultiDependency("config");

    //main logic
    var reporter = new Reporter(sharedDependency, colorDependency, configDependency);
    reporter.DoSomething();
}
?

(颜色和配置值都来自app.config文件,不是硬编码的。正如我所说,上面是泛化的,真实的项目有更多的依赖关系,依赖关系的依赖关系,其中一些比其他的更共享。)

第一种方法更有效,因为CSharedDependency只创建一次,CColordDependency只创建两次。第二个是完全配置驱动的,因此不需要维护,并且完全可扩展


那么,哪一种设计是最好的呢?

组织应用程序进行依赖项注入的正确方法(无论是使用容器还是容器)是在应用程序启动时使用一个来组成应用程序的对象图

因此,您的第一个示例看起来更符合这一点,因为您永远不会在运行时访问容器来创建依赖项,而是创建这些实例

也就是说,从您的示例中不清楚您是如何组织应用程序的。如果没有组合根,则无法正确执行依赖项注入。既然你不得不问这个问题,我怀疑你没有合成根,因为如果你有,你的第二个例子就永远不会起作用

参考资料:


组织应用程序进行依赖项注入(无论是使用容器还是容器)的正确方法是在应用程序启动时使用来组成应用程序的对象图

因此,您的第一个示例看起来更符合这一点,因为您永远不会在运行时访问容器来创建依赖项,而是创建这些实例

也就是说,从您的示例中不清楚您是如何组织应用程序的。如果没有组合根,则无法正确执行依赖项注入。既然你不得不问这个问题,我怀疑你没有合成根,因为如果你有,你的第二个例子就永远不会起作用

参考资料:


据我所知,问题在于在第二个备选方案中,
SharedDependency
被多次创建,而且
ColorDependency
实例的创建次数也超过了必要的次数

我对此的第一反应是,这可能无关紧要。如果您遵循这样的规则,创建一些超出需要的对象很可能是您不会注意到的—特别是当这些对象随后参与I/O时。在.NET中创建对象很快(而I/O很慢)

尽管如此,“问题”可能很容易解决

如果希望完全由配置驱动,则需要一种方法来区分不同的配置值组。最简单的方法很可能是在
appSettings
键前面加上众所周知的前缀,但更可靠的方法是定义自定义配置节

在任何情况下,我都假设您可以从配置系统中提取两个集合:
colors
configs

这将使以配置驱动的方式创建服务变得容易:

var sharedDependency = new SharedDependency();
foreach (var color in colors)
{
    var colorDependency = new ColorDependency(color);

    foreach (var config in configs)
    {
        var configDependency = new MultiDependency(config);

        //main logic
        var reporter = new Reporter(sharedDependency, colorDependency, configDependency);
        reporter.DoSomething();
    }
}
综上所述,在你开始重新发明轮子之前:大多数DI容器都支持通过
app.config
进行配置,因此这可能也是你的一个选择

又一次:那就说,考虑一下到底是不是。使用基于文本的配置,您将丢失。你也可以很容易地结束


除非您有令人信服的理由在配置文件中配置对象图,否则请支持。

据我理解,这个问题的关键在于,在第二个备选方案中,
SharedDependency
被多次创建,而且
ColorDependency
实例的创建次数也超过了必要的次数

我对此的第一反应是,这可能无关紧要。如果您遵循这样的规则,创建一些超出需要的对象很可能是您不会注意到的—特别是当这些对象随后参与I/O时。在.NET中创建对象很快(而I/O很慢)

尽管如此,“问题”可能很容易解决

如果希望完全由配置驱动,则需要一种方法来区分不同的配置值组。最简单的方法很可能是在
appSettings
键前面加上众所周知的前缀,但更可靠的方法是定义自定义配置节

在任何情况下,我都假设您可以从配置系统中提取两个集合:
colors
configs

这将使以配置驱动的方式创建服务变得容易:

var sharedDependency = new SharedDependency();
foreach (var color in colors)
{
    var colorDependency = new ColorDependency(color);

    foreach (var config in configs)
    {
        var configDependency = new MultiDependency(config);

        //main logic
        var reporter = new Reporter(sharedDependency, colorDependency, configDependency);
        reporter.DoSomething();
    }
}
综上所述,在你开始重新发明轮子之前:大多数DI容器都支持通过
app.config
进行配置,因此这可能也是你的一个选择

又一次:那就说,考虑一下到底是不是。使用基于文本的配置,您将丢失。你也可以很容易地结束

除非您有令人信服的理由在配置文件中配置对象图,否则请支持。

如果您查看您提供的参考资料中的“控制台应用程序中的纯DI”部分,这正是我所拥有的:在main()中有一个具有纯DI和依赖项构造的控制台应用程序。“entryPoint.Run()”基本上是我的“reporter.DoSomething()”。唯一的di