Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/github/3.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
Dependency injection DI容器:如何将配置传递给对象_Dependency Injection_Inversion Of Control - Fatal编程技术网

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

Dependency injection DI容器:如何将配置传递给对象,dependency-injection,inversion-of-control,Dependency Injection,Inversion Of Control,有时我会上一些课程,这些课程需要获取一些关于建筑的信息。我说的不是对其他对象(将被注入)的引用,而是(例如)包含唯一信息的字符串: // Scoped as singleton! class Repository { public Repository( InjectedObject injectedObject, string path ) { ... } } 你是怎么注射的?一种可能性是编写Init()方法,并避免字符串的注入: class Repository { pub

有时我会上一些课程,这些课程需要获取一些关于建筑的信息。我说的不是对其他对象(将被注入)的引用,而是(例如)包含唯一信息的字符串:

// Scoped as singleton!
class Repository
{
    public Repository( InjectedObject injectedObject, string path ) { ... }
}
你是怎么注射的?一种可能性是编写
Init()
方法,并避免字符串的注入:

class Repository
{
    public Repository( InjectedObject injectedObject ) { ... }
    public void Init( string path ) { ... }
}
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
}
另一种可能是将信息包装到对象中,对象可以被注入:

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 ) { ... }
}
但同样,这是一个工厂,仅用于单个对象…
或者,最后,由于路径将从配置文件中提取,我可以跳过传递字符串并在构造函数中读取配置(这可能不是最优的,但可能是可行的):


你最喜欢的方法是什么?对于非单例类,您必须使用imho的
Init()
或工厂解决方案,但是单例范围的对象呢?

如果您使用构造函数注入,我发现向构造函数添加一个作为配置对象的参数是最好的方法。通过使用init函数,您在某种程度上避开了构造函数注入点。这使得测试更加困难,也使得维护和交付更加困难


发现成为一个问题,因为此类是否需要配置对象并不明显。通过将其添加到构造函数中,使用此对象的任何人都明确知道此配置必须存在。

我不希望让DI容器指定我的API设计。容器应符合适当的设计,而不是相反

以某种方式设计类,但不要对DI容器做出让步。如果需要连接字符串,则通过构造函数获取字符串:

public class Repository : IRepository
{
    public Repository(string path) { //... }
}
许多DI容器可以处理原语值。举个例子,这里有一种方法可以在温莎实现这一点:

container.Register(Component.For<IRepository>()
    .ImplementedBy<Repository>()
    .DependsOn( new { path = "myPath" } ));
现在,您可以简单地告诉您的容器将
IRepository
映射到
ConfiguredRepository
,同时保持核心存储库实现的干净

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
}