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