c# - 如何将依赖注入(inject)应用于抽象工厂

标签 c# dependency-injection

我刚刚读完了 Mark Seemann 的书.NET 中的依赖注入(inject),现在我正在尝试重构一些遗留代码。 (在这个阶段,我不依赖于任何特定的 DI 容器,而只是试图将所有依赖项移动到一个地方)。

我正在查看以下工厂类,它通过使用 archiveReader.GetArchiveType() 读取存档的前几个字节来确定 ArchiveType,然后返回一个实例ArchiveRestorer 基于 ArchiveType 枚举。

public class ArchiveRestorerFactory : IArchiveRestorerFactory
{
    public ArchiveRestorer Create(ArchiveReader archiveReader)
    {
        ArchiveType type = archiveReader.GetArchiveType();
        switch (type)
        {
            case ArchiveType.CurrentData:
                return new CurrentDataArchiveRestorer(archiveReader);
                break;
            case ArchiveType.HistoricalData:
                return new HistoricalDataArchiveRestorer(archiveReader);
                break;
            case ArchiveType.AuditTrail:
                return new AuditTrailArchiveRestorer(archiveReader);
                break;
            default:
                throw new Exception("ArchiveRestorerFactory error: Unknown value for ArchiveType.");
        }
    }
}

如何重构它,使该类不依赖于具体类型 CurrentDataArchiveRestorerHistoricalDataArchiveRestorerAuditTrailArchiveRestorer

我是否应该将三个混凝土恢复器移到工厂的构造器中?

public ArchiveRestorer Create(ArchiveReader archiveReader, 
    ArchiveRestorer currentDataArchiveRestorer, 
    ArchiveRestorer historicalDataArchiveRestorer, 
    ArchiveRestorer auditTrailDataArchiveRestorer)
{
    // guard clauses...
    // assign to readonly fields
}

这似乎是建议的方法here ,但是当只需要一个恢复器时它会实例化所有三个恢复器?如果我有 20 种不同的可能的具体实现呢?

我觉得我应该为每种类型的恢复器实现一个具体的工厂并返回它,但我只是将一个 new 替换为另一个。

重构它的最佳方法是什么?

最佳答案

根据您已有的代码,我这样做的方法是为每个具有 Create() 方法的对象创建一个工厂。

我也有一个用于这些工厂的接口(interface),并让它们继承自通用工厂接口(interface)。

然后您可以使用这些接口(interface)作为注入(inject)构造函数的点。

这将被称为类似这样:

case ArchiveType.CurrentData:
                return _currentDateArchiveRestorerFactory.Create(archiveReader);
                break;

或者,最好有一个工厂来创建给定类型的实例。由于所有这些对象都是恢复器,您可以只基于 enum 而不是 switch 创建实例。

_restorerFactory.Create(ArchiveType.CurrentData);

关于c# - 如何将依赖注入(inject)应用于抽象工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9117403/

相关文章:

asp.net-mvc - Ninject,如何通过调用 LoggerFactory.CreateLogger 注入(inject)通用 Logger<T>

c# - 如何使用具有 "greedy"构造函数的 Scan 将 StructureMap 与通用未封闭类型一起使用

c# - 可靠的发布/订阅

c# - 运行程序需要哪些 C++ 包?

C# - 查找 Sharepoint 文件的本地目录

c# - 无法在调试文件夹之外运行 .NET C# 应用程序

angularjs - : [$injector:unpr] Unknown provider in angularjs can't inject factory into controller

c# - 将 C# 日期时间对象转换为 Excel 日期格式

dependency-injection - 依赖注入(inject)带来的性能问题

android - Dagger:如果我每次都*想要*一个新实例怎么办?