DI容器:如何将配置传递给对象

5
有时我需要在课程中获取一些构建信息。我不是指对其他对象的引用(将被注入),而是指保存唯一信息的字符串(例如)。
// Scoped as singleton!
class Repository
{
    public Repository( InjectedObject injectedObject, string path ) { ... }
}

你如何注入这个字符串?一种可能性是编写一个Init()方法并避免字符串注入:

class Repository
{
    public Repository( InjectedObject injectedObject ) { ... }
    public void Init( string path ) { ... }
}

另一种可能性是将信息封装成对象,然后进行注入:

class InjectedRepositoryPath
{
    public InjectedRepositoryPath( string path ) { ... }
    public string Path { get; private set; }
}

class Repository
{
    public Repository( InjectedObject injectedObject, InjectedRepositoryPath path ) { ... }
}

这样,我需要在 DI 容器初始化期间创建一个 InjectedRepositoryPath 实例并注册该实例。但是,我需要为每个类创建这样一个唯一的配置对象。
当然,我可以解析 RepositryFactory 而不是 Repository 对象,这样工厂就会要求我提供路径:
class RepositoryFactory
{
    Repository Create( string path ) { ... }
}

但是,这只是为单例对象设计的一个工厂...
或者,最后,由于路径将从配置文件中提取,我可以跳过传递字符串并在我的构造函数中读取配置(这可能不是最优的,但可行):

class Repository
{
    public Repository( InjectedObject injectedObject )
    {
        // Read the path from app's config
    }
}

你最喜欢的方法是什么?对于非单例类,您需要使用Init()或工厂解决方案,但对于单例作用域对象呢?

2个回答

4
如果您正在使用构造函数注入,我认为将配置对象作为参数添加到构造函数中是最好的方法。通过使用init函数,您有点绕开了构造函数注入的重点。这使得测试更加困难,也使得维护和交付更加困难。
发现成为一个问题,因为不容易看出这个类需要一个配置对象。通过将其添加到构造函数中,任何使用此对象的人都明确知道必须存在此配置。

2

我希望不要让DI容器来决定我的API设计。容器应该符合正确的设计,而不是反过来。

DI友好的方式设计您的类,但不要对DI容器做出让步。如果需要连接字符串,则通过构造函数传递一个字符串:

public class Repository : IRepository
{
    public Repository(string path) { //... }
}

许多 DI 容器都可以处理原始值。以下是使用 Windsor 处理原始值的一种方法示例:
container.Register(Component.For<IRepository>()
    .ImplementedBy<Repository>()
    .DependsOn( new { path = "myPath" } ));

然而,如果您选择的容器无法处理原始参数,您可以始终使用一个实现来装饰Repository以知道如何查找字符串:

public class ConfiguredRepository : IRepository
{
    private readonly Repository decoratedRepository;

    public ConfiguredRepository()
    {
        string path = // get the path from config, or whereever appropriate
        this.decoratedRepository = new Repository(path);
    }

    // Implement the rest of IRepository by
    // delegating to this.decoratedRepository
}

现在,您可以直接告诉您的容器将IRepository映射到ConfiguredRepository,同时保持核心存储库实现的清晰。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接