【问题标题】:Ninject bind all classes implementing the same interfaceNinject 绑定所有实现相同接口的类
【发布时间】:2013-03-08 09:10:17
【问题描述】:

我有一个接口类:

public interface IStartUpTask
{
    bool IsEnabled { get; }
    void Configure();
}

我有多个实现相同接口的类

其中一个类如下所示:

public class Log4NetStartUpTask : IStartUpTask
{
    public bool IsEnabled { get { return true; } }

    public void Configure()
    {
        string log4netConfigFilePath = ConfigurationManager.AppSettings["log4netConfigFilePath"];
        if (log4netConfigFilePath == null)
            throw new Exception("log4netConfigFilePath configuration is missing");

        if (File.Exists(log4netConfigFilePath) == false)
            throw new Exception("Log4Net configuration file was not found");

        log4net.Config.XmlConfigurator.Configure(
            new System.IO.FileInfo(log4netConfigFilePath));
    }
}

我如何告诉 Ninject 我希望所有实现 IStartUpTask 的类自动绑定到自己?

我找到了一个使用 StructureMap 的示例,但我不知道如何在 Ninject 中执行此操作。

Scan(x => {
    x.AssemblyContainingType<IStartUpTask>();
    x.AddAllTypesOf<IStartUpTask>();
    x.WithDefaultConventions();
});

【问题讨论】:

    标签: dependency-injection ninject


    【解决方案1】:

    我如何告诉 Ninject 我希望所有类都实现 IStartUpTask 自动绑定到自己?

    首先,让我告诉你,Ninject 会自动将所有类绑定到它们自己。你不需要为此做任何特别的事情。

    话虽如此,我知道如果您想更改范围或附加名称或元数据,您可能需要显式绑定。在这种情况下,请继续阅读。

    我不知道是否可以在 vanilla ninject 中做你想要的,但你可以使用ninject.extensions.conventions。使用这个库你可以写:

    Kernel.Bind(x => 
        x.FromThisAssembly()
        .SelectAllClasses()
        .InheritedFrom<IStartUpTask>()
        .BindToSelf());
    

    【讨论】:

    • 这种方法对我有用,但我必须做 'BindSingleInterface' 而不是 BindToSelf。但无论如何,对我来说诀窍是“InheritedFrom”位。谢谢!
    • 我找到了这个解决方案,但它对我来说“不起作用”。我花了一段时间才找出原因,所以我在这里添加它以添加更多上下文。默认情况下,Ninject 只绑定公共类,如果你想绑定内部类,你必须调用IncludingNonePublicTypes() 方法。
    • 与@noocyte 相同。
    【解决方案2】:

    您可以在代码中显式调用它:

    ...
    Bind<IStartUpTask>().To<Log4NetStartUpTask>();
    Bind<IStartUpTask>().To<SomeOtherStartUpTask>();
    ...
    

    在 SomeClass 中使用它

    public class SomeClass
    {
       private readonly List<IStartUpTask> startUpTaskList;
    
       public SomeClass(IEnumerable<IStartUpTask> startUpTaskList)
       {
          this.startUpTaskList = startUpTaskList;
       }
    
       foreach (var startUpTask in this.startUpTaskList)
       {
          ...
       }
    }
    

    【讨论】:

    • 最后一个绑定不会覆盖之前的绑定?
    • @MikroDel:那么在您的示例中,当需要 IStartUpTask 接口时将注入哪个类?这看起来不对。
    • @RaraituL 我已经更新了我的答案以使其更容易理解
    • @MikroDel:他不是这么问的。
    • 这里的关键点是,如果有多个绑定到同一类型(在这种情况下,Log4NetStartupTaskSomeOtherStartupTask 被绑定到 IStartupTask),那么您要么必须提供额外的找到要注入的IStartupTask 的一个唯一实现,或将所有实现注入为IEnumerable&lt;IStartupTask&gt; 的条件。绑定不会相互覆盖。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-02
    • 1970-01-01
    相关资源
    最近更新 更多