2010-02-19 50 views
4

有时我需要获取某些构造信息的类。我不是在谈论到其他对象(其将被注入),但有关(例如)的字符串,其持有唯一的参考信息:DI容器:如何将配置传递给对象

// 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) { ... } 
} 

这样我d在我的DI容器的初始化期间必须创建一个InjectedRepositoryPath的实例并注册这个实例。但是我需要为每个类似的类提供这样一个独特的配置对象。

我当然可以解决RepositryFactory代替Repository对象,因此工厂会问我要的路径:

class RepositoryFactory 
{ 
    Repository Create(string path) { ... } 
} 

但同样,这是一个工厂只为一个单独的对象...
或者,最后,由于路径将会从配置文件中提取,我可以跳过字符串周围的传球和我的构造函数读取配置(这可能不是最优的,但有可能):

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

你最喜欢的方法是什么?对于非单身人士课程,您必须使用imho Init()或工厂解决方案,但单身人士范围的对象又如何?

回答

2

我更喜欢没有DI容器指定我的API设计。容器应该符合正确的设计,而不是相反。

DI-friendly的方式设计您的课程,但不会对您的DI容器做出让步。如果您需要连接字符串,请通过构造函数获取字符串:

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

许多DI容器可以处理原始值。作为一个例子,这里有温莎做到这一点的一种方法:

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 
} 

现在你可以简单地告诉你的容器映射IRepositoryConfiguredRepository,同时仍保持核心库推行清洁。

+0

非常有趣的链接,谢谢你的答案! – tanascius 2010-02-22 16:20:20

3

如果你正在使用构造函数注入,我发现添加一个参数是你的配置对象的构造函数是最好的方法。通过使用一个init函数,你有点回避构造函数注入的问题。这使得测试更加困难,这也使得维护和交付更加困难。

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

+0

我也有同样的感觉。 – Kangkan 2010-02-19 16:38:53

相关问题