使用Unity如何将InjectionConstructor注入封闭源API(Lucene)

时间:2012-10-12 06:07:49

标签: c# .net dependency-injection inversion-of-control unity-container

我对DI和IoC都很陌生,所以你可以想象我现在开始使用Unity容器让这个应用程序正常运行。问题是当我想在Lucene的StandardAnalyzer上使用DI时,我收到以下错误:

  

StandardAnalyzer类型有多个长度为2的构造函数。   无法消除歧义。

所以我理解的是,Unity Container正在寻找具有最多参数的构造函数,但因为有多个它不能告诉哪一个。正如您将在下面的代码中看到的那样,构造函数只是想使用带有一个类型Version的参数(来自Lucene命名空间)。我尝试使用InjectionConstructor,但无法让它发挥作用,我开始认为这可能无法实现。有什么帮助吗?

private const string Analyzer = "analyzer";
private const string Logging = "logging";
private const string FsDirectory = "fsDirectory"; 
private const string IndexWriter =   "indexWriter";

var analyzer = new StandardAnalyzer(Version.LUCENE_29);
var fsDirectory = FSDirectory.Open(new DirectoryInfo(
    new AppConfig().DatabaseName()));
var indexWriter = new IndexWriter(fsDirectory, analyzer, 
    new IndexWriter.MaxFieldLength(int.MaxValue));

this.RegisterType<StandardAnalyzer>(new InjectionConstructor(
    new ResolvedParameter<Version>(Analyzer)));
//RegisterInstance(typeof(StandardAnalyzer), Analyzer, analyzer, 
//    new ContainerControlledLifetimeManager());
RegisterInstance(typeof(FSDirectory), FsDirectory, fsDirectory, 
    new ContainerControlledLifetimeManager());
RegisterInstance(typeof(IndexWriter), IndexWriter, indexWriter, 
    new ContainerControlledLifetimeManager());

this.RegisterType<IDocumentIndexerWithLucene, DocumentIndexerWithLucene>(
    new ContainerControlledLifetimeManager(),
    new InjectionConstructor(
        new ResolvedParameter(typeof(StandardAnalyzer), Analyzer),
        new ResolvedParameter(typeof(Logging), Logging), 
        new ResolvedParameter(typeof(FSDirectory), FsDirectory),
        new ResolvedParameter(typeof(IndexWriter), IndexWriter)));

1 个答案:

答案 0 :(得分:3)

对于静态依赖项(外部库或.NET框架中的类型),通常不应使用自动布线(自动构造函数注入),而是注册创建该类型的委托。自动构造函数注入有助于使Composition Root更易于维护,因为这允许您更改类型的构造函数,而无需更改组合根。另一方面,静态依赖性不会经常改变,因此可维护性不是他们的问题。另一方面,静态依赖关系通常不是DI友好的,并且可以包含多个构造函数,这些构造函数可以使自动连接更加困难(正如您所经历的那样)。更糟糕的是,即使您在静态类型上进行自动布线工作,升级到该外部的较新版本也可能会破坏您的组合根,因为可以引入新的构造函数(这证明every change is a breaking change)与您的DI容器不兼容。

因此,解决方案是注册手动创建该类型的委托:

container.Register<IService>(new InjectionFactory(c => 
    new StandardAnalyzer(Version.LUCENE_29)));