阅读Mark Seemann的书 - .NET中的依赖注入使我更多地考虑实现他的概念,但也观察了一些缺失的部分。
他详细说明了构造函数注入的各个方面以及应该在何处进行,以及如何进行,但他对于一个属性的注入时间说得很少。
如果只有Composition Root应该是我唯一知道所有依赖关系的入口点,那么应该将属性设置为新依赖关系(因为本地默认值是必需的)?
如果我立即在CR中这样做,那么本地默认点是什么?
因此,为了以正确的方式使用Property Injection模式,我是否只能从同一个程序集中分配实现,这些实现可以在Composition Root之外的任何位置?
这当然会导致模糊的水域,让我想知道界面属性是否总体上仍然有用?
如果抽象属性的主要目的是允许策略(设计模式),那么最好也可以在我的构造函数中注入抽象工厂?
回答: @Siram Sakthivel,我将对它进行投票,因为我确信这个漂亮的架构对于没有Mark的书的人来说是非常有建设性的。我并不高兴,因为在本书中还指出必须知道并在CR内部分配所有依赖项(方法注入和环境上下文除外)。所以马上就开始吧!为什么在我已经有本地默认值时,在开始时初始化CR内的属性?如果我选择不这样做(因为当地的默认值),那么我只能在同一个程序集中使用具体类型的情况下继续这样做,因为否则我将会前进正如你提到的那样,错误的方式(Bastard注射)。
策略模式源四人帮.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 ");
}
}
答案 0 :(得分:4)
在合成对象时,属性注入并不特别。你必须像使用构造函数注入那样做。唯一不同的是,使用构造函数注入,您将无法在不传递依赖项的情况下创建实例。这是强制性的。
另一方面,属性注入是可选的。你可以注入一个财产;你可能不会。但即使你不注入财产,这个课程也不会受到影响;因为本地默认值已经可用(属性注入要求)。
如果我立即在CR中这样做,那么本地的意义何在? 默认?
即使客户端没有注入属性,本地默认也可以帮助该类工作。它是可选的,你可以注入它,不一定是你总是注入。
所以,为了正确使用Property Injection模式,我 约束仅分配来自同一程序集的实现 哪个可以在Composition Root之外的任何地方?
如果问题中的类提供了本地默认值,则它应该在同一个程序集中定义,如果它引用其他某个程序集,那么它将被称为Bastard Injection反模式,你想要避免它。
从组合根注入时,可以从任何组件中注入任何依赖项。
这当然会导致模糊的水域让我想知道是否 接口属性总体上还有用吗?
我不确定你的意思;如果您可以在另一个程序集中实现该接口并将其注入组合根目录,则作为接口类型公开的属性会很有用。不一定在另一个程序集中,您可以在同一个程序集中拥有多个实现,但这并不常见。
请记住,您必须努力使用构造函数注入。如果构造函数注入无法满足您的需求,则只使用其他模式。
在选择使用哪种类型的注射模式时,Mark Seemann选择注射模式的流程图对他有帮助。请参阅.NET中的依赖注入 - Mark Seemann Page 131。