Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.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# 财产应该注入哪里?_C#_Design Patterns_Dependency Injection - Fatal编程技术网

C# 财产应该注入哪里?

C# 财产应该注入哪里?,c#,design-patterns,dependency-injection,C#,Design Patterns,Dependency Injection,在.NET中阅读Mark Seemann的书-依赖注入使我更多地思考如何实现他的概念,但也观察到一些缺失的部分。 他详细说明了构造函数注入的各个方面,应该在哪里进行,以及如何进行,但他很少提到属性的注入时间 如果只有合成根应该是我唯一知道所有依赖项的入口点,那么应该在哪里为新的依赖项设置属性,因为本地默认值是必需的 如果我在CR中立即这样做,那么本地违约有什么意义 因此,为了正确地使用属性注入模式,我是否必须只分配来自同一程序集的实现,这些实现可以位于组合根之外的任何位置 这当然会导致模糊的水域

在.NET中阅读Mark Seemann的书-依赖注入使我更多地思考如何实现他的概念,但也观察到一些缺失的部分。 他详细说明了构造函数注入的各个方面,应该在哪里进行,以及如何进行,但他很少提到属性的注入时间

如果只有合成根应该是我唯一知道所有依赖项的入口点,那么应该在哪里为新的依赖项设置属性,因为本地默认值是必需的

如果我在CR中立即这样做,那么本地违约有什么意义

因此,为了正确地使用属性注入模式,我是否必须只分配来自同一程序集的实现,这些实现可以位于组合根之外的任何位置

这当然会导致模糊的水域,让我想知道,如果一个接口属性整体上仍然有用吗

如果抽象属性的主要目的是允许策略设计模式,那么我可能更适合在构造函数中最终注入抽象工厂

答复: @Siram Sakthivel,我会投赞成票,因为我确信这是一个美丽的模式,对于没有马克的书的其他人来说是非常有建设性的。我不高兴,因为书中还规定,除了方法注入和环境上下文之外,所有依赖项都必须在CR中被知道和分配。因此,在开始时立即!既然我已经有了本地默认值,为什么要在开始时初始化CR中的属性?如果我选择不这样做是因为本地默认值,那么我只能使用同一程序集中的具体类型来执行,因为否则我将以错误的方式前进,正如您漂亮地提到的那样

战略模式来源四人帮.Net优化我买了那该死的东西:

 static void Main()
    {
        // Two contexts following different strategies
        var studentRecords = new SortedList()
          {
            new Student{ Name = "Samual", Ssn = "154-33-2009" },
            new Student{ Name = "Jimmy", Ssn = "487-43-1665" },
            new Student{ Name = "Sandra", Ssn = "655-00-2944" },
            new Student{ Name = "Vivek", Ssn = "133-98-8399" },
            new Student{ Name = "Anna", Ssn = "760-94-9844" },
          };

        studentRecords.SortStrategy = new QuickSort();
        studentRecords.SortStudents();

        studentRecords.SortStrategy = new ShellSort();
        studentRecords.SortStudents();

        studentRecords.SortStrategy = new MergeSort();
        studentRecords.SortStudents();

        // Wait for user
        Console.ReadKey();
    }
}

/// <summary>
/// The 'Strategy' interface
/// </summary>
interface ISortStrategy
{
    void Sort(List<Student> list);
}

 /// <summary>
/// A 'ConcreteStrategy' class
/// </summary>
class ShellSort : ISortStrategy
{
    public void Sort(List<Student> list)
    {
        // ShellSort();  not-implemented
        Console.WriteLine("ShellSorted list ");
    }
}

/// <summary>
/// A 'ConcreteStrategy' class
/// </summary>
class MergeSort : ISortStrategy
{
    public void Sort(List<Student> list)
    {
        // MergeSort(); not-implemented
        Console.WriteLine("MergeSorted list ");
    }
}

属性注入在组合对象时没有什么特别之处。您必须像使用构造函数注入一样执行此操作。唯一的区别是,使用构造函数注入,如果不传递依赖项,就无法创建实例。这是强制性的

另一方面,属性注入是可选的。您可以注入一个属性;你可能不会。但类是问题,即使不注入属性,也不会受到影响;因为本地默认值已经可用,所以需要属性注入

如果我在CR中立即这样做,那么本地 违约

本地默认值帮助类工作,即使客户端不注入属性。它是可选的,您可以注入它,但不一定总是注入

那么,为了正确地使用属性注入模式,是吗 约束为仅分配来自同一程序集的实现 哪一个可以位于合成根之外的任何位置

如果问题中的类提供了本地默认值,则应在同一程序集中定义该类,如果该类引用了其他程序集,则称其为您希望避免的反模式

当您从组合根注入依赖项时,可以从任何程序集注入依赖项

这当然会导致模糊的水域,让我怀疑 接口属性总体上仍然有用吗

我不知道你这是什么意思;如果可以在另一个程序集中实现接口并将其注入到组合根目录中,则作为接口类型公开的属性很有用。不一定在另一个程序集中,您可以在同一个程序集中有多个实现,但这并不常见

请记住,您必须始终努力使用构造函数注入。只有当构造函数注入不能满足您的需求时,才使用其他模式

在选择使用哪种类型的注射模式时,Mark Seemann的注射模式选择流程图将非常有用。请参阅.NET-Mark Seemann第131页中的依赖项注入


请务必阅读我在问题中的答案,这里的空间不够,我认为你没有抓住重点。一个很好的例子是,可以使用属性ConsoleLogger将日志记录实现为本地默认值,该属性将写入控制台,但如果希望将其写入数据库或其他内容,则需要创建DatabaseLogger并将其注入到composition root中。有了这99%,您将只使用本地默认的ConsoleLogger,但它允许您自由地登录到任何提供ILogger作为您可以注入的属性的地方。我想不出更好的例子,通常Logger不会用作属性注入,这是一个人为的例子。如果在某个特殊时刻,我想停止使用ConsoleLogger并使用DatabaseLogger,我该怎么做,在我的应用程序运行时更新合成根目录?请记住,依赖项只能分配一次,这是他说的!更多的是,你在帮助我树立榜样
我越是意识到这是整个概念中的一个流程。我坚持使用-if是一个属性注入,然后将它作为一种策略,只使用它自己的程序集中的类型。请看一下我的回答中的策略模式。是的,如果你想交换实现,你必须修改CR并重新编译你的应用程序。如果不想重新编译,可以将类名存储在app.config中,并使用Activator.CreateInstance动态实例化。这样,您就不必重新编译应用程序。您可以根据需要多次注入该属性。没有什么能阻止你做这件事。Mark在他的书中多次阻止设置该属性,因为它适合他的示例,而不是因为模式本身要求它。书中包含了一个列表,其中列出了您应该注入的项和您可能不应该注入的项。查找有关易失性和非易失性依赖项的信息。此外,本书还包含一个流程图,突出显示了何时使用哪种类型的注射。容易的