Unity . net:依赖列表

本文关键字:列表 依赖 net Unity | 更新日期: 2023-09-27 18:09:01

是否有可能在Unity或其他类型的IoC库中注入像这样的依赖项列表 ?

public class Crawler 
{
    public Crawler(IEnumerable<IParser> parsers) 
    {
         // init here...
    }
}

通过这种方式,我可以在容器中注册多个IParser,然后解析它们。

有可能吗?由于

Unity . net:依赖列表

这是可能的,但您需要应用一些变通方法。首先,你需要在Unity容器中注册每个 isparser 的名称。其次,你需要在容器中注册一个从IParser[]IEnumerable的映射。否则,容器不能将解析器注入构造函数。这是我以前是怎么做的。

IUnityContainer container = new UnityContainer();
container.RegisterType<IParser, SuperParser>("SuperParser");
container.RegisterType<IParser, DefaultParser>("DefaultParser");
container.RegisterType<IParser, BasicParser>("BasicParser");
container.RegisterType<IEnumerable<IParser>, IParser[]>();
container.RegisterType<Crawler>();
Crawler crawler = container.Resolve<Crawler>();
通过引入工厂,我放弃了这个解决方案,工厂封装了unity来构造所需的类型。以下是我将如何为你做这件事。
public interface IParserFactory{
  IEnumerable<IParser> BuildParsers();
}
public class UnityParserFactory : IParserFactory {
  private IUnityContainer _container;
  public UnityParserFactory(IUnityContainer container){
    _container = container;
  }
  public IEnumerable<IParser> BuildParsers() {
    return _container.ResolveAll<IParser>();
  }
}
public class Crawler {
  public Crawler(IParserFactory parserFactory) {
     // init here...
  }
}

可以这样注册类型:

IUnityContainer container = new UnityContainer();
container.RegisterType<IParser, SuperParser>();
container.RegisterType<IParser, DefaultParser>();
container.RegisterType<IParser, BasicParser>();
container.RegisterType<IParserFactory, UnityParserFactory>();
Crawler crawler = container.Resolve<Crawler>();

不是我说这是错的,但似乎你正试图解决一个插件模型,你可以很容易地管理使用MEF代替。提示将从接口继承Export,然后在需要解析器时执行ImportMany。

在Unity中有很多方法可以实现这一点。例如,

http://sharpsnmplib.codeplex.com/SourceControl/changeset/view/5497af31d15e snmpd % 2 fapp.config

    <register type="UserRegistry">
      <lifetime type="singleton" />
      <constructor>
        <param name="users" dependencyType="User[]" />
      </constructor>
    </register>

这个构造函数需要一个User对象数组,并且当UserRegistry对象被创建时,所有在这个容器中定义的对象都会被Unity注入其中。

事实上,我不知道任何不支持的容器。

然而,作为一般建议,如果可以的话,应该避免将服务列表注入消费者,方法是将该列表包装在一个组合中,然后将该组合注入消费者。不将列表包装在复合中会使应用程序因额外的foreach循环或处理依赖项列表所需的任何操作而变得混乱。虽然这看起来并不糟糕,但这些依赖项的消费者不应该在意。但更糟糕的是,当我们想要更改服务列表的处理方式时,我们将不得不检查整个应用程序,这违反了DRY原则。

当消费者(在您的例子中是Crawler)是组合根的一部分而不是应用程序本身时,此建议不成立。此外,当应用程序只有一个使用此依赖项的消费者时,这可能不是什么大问题。

你可以…您可以查看依赖注入器。我是autoface项目的超级粉丝。

另一个选项是Ninject