使用Ninject,我可以在不暴露我的具体类的情况下从接口创建实例吗?

问题描述 投票:10回答:3

到目前为止我所看到的样本看起来像这样:

像这样写代码...

public class Samurai {
  public IWeapon Weapon { get; private set; }
  public Samurai(IWeapon weapon) {
    Weapon = weapon;
  }
}

并且Ninject可以像这样将接口映射到具体类型...

public class WarriorModule : NinjectModule {
  public override void Load() {
    Bind<IWeapon>().To<Sword>();
  }
}

所以当我在武士对象中说var samurai = kernel.Get<Samurai>();时,我的IWeapon自动就是一剑。

这很酷,但是如果我只想要没有武士和混凝土剑的ISword标记为内部剑,该怎么办?

[目前,我使用自制的依赖项解析器,在这里我可以说var sword = DependencyResolver.Current.Resolve<ISword>();,它给了我一个Sword转换为ISword的信息。我的具体类被标记为内部类,因此开发人员必须通过我的依赖关系解析器创建实例。 Ninject是否有与此相似的东西?

还有一个额外的问题,我用自定义“ DefaultConcreteType”属性修饰我的接口,如果没有映射,则依赖解析程序可以使用该属性。 Ninject是否也有类似的东西?

谢谢

c# dependency-injection inversion-of-control ninject
3个回答
15
投票

将接口绑定到具体类型时,您可以要求该接口的实例并获取具体类型。在您的示例中,您可以执行以下操作:

var sword = kernel.Get<ISword>();

这将为您提供一个具体的Sword对象。您也可以使用绑定系统做更多的事情。您甚至可以Bind<ISword>().ToMethod(MySwordFactory);并编写一种根据请求上下文获取Swords的方法。

您可以做的另一件事是根据注入的类型更改绑定的工作方式。例如,您可以在自定义类上公开一个属性,如下所示:

public class MyClass {
    [Inject]
    public ISword Sword { get; set; }
}

然后您可以绑定到基于MyClass的特定ISword实现:

Bind<ISword>().To<Sword>().WhenInjectedInto<MyClass>();

还有很多选择,但这应该为您提供一个大概的概述。


0
投票

我建议使用可以创建ISword的抽象工厂。与DependencyResolver相比,它的优势在于它可以创建的类型是有界的(为ISword)。

您的抽象工厂将是公共的,就像您的DependencyResolver。


0
投票

这不能直接回答您的问题,但是我知道使用Unity,您可以通过使用Config文件来完成此任务,而不必在代码中连接依赖项。遗憾的是,Ninject不支持Config文件。

您的替代方法是使用非通用重载:

Bind(typeof(IWeapon)).To(typeof(Sword));

然后您应该可以执行以下操作:

Bind(typeof(IWeapon)).To(Type.GetType("MyNamespace.MyInternalSword"))

但是如果您问我,那真是太丑了。...

© www.soinside.com 2019 - 2024. All rights reserved.