到目前为止我见过的样本看起来像这样:
像这样编写你的代码......
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有这样的东西吗?
由于
答案 0 :(得分: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>();
还有很多选择,但这应该给你一个粗略的概述。
答案 1 :(得分:0)
我建议使用可以创建ISword
的抽象工厂。这比DependencyResolver
有一个优势,因为它可以创建的类型是有界的(到ISword
)。
您的抽象工厂需要公开,就像您的DependencyResolver一样。
答案 2 :(得分:0)
这并没有直接回答你的问题,但我知道在Unity中,你可以通过使用Config文件而不是在代码中连接依赖项来实现。不幸的是,Ninject不支持配置文件。
您的替代方法是使用非泛型重载:
Bind(typeof(IWeapon)).To(typeof(Sword));
然后你应该可以做类似的事情:
Bind(typeof(IWeapon)).To(Type.GetType("MyNamespace.MyInternalSword"))
但如果你问我,那就太大了......