2011-03-15 53 views
10

我到目前为止看到像这样的样本:使用Ninject,我可以在不暴露具体类的情况下从界面创建实例吗?

编写代码是这样的...

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>();时,我的武器自动成为剑。

这很酷,但是如果我只想要没有武士的ISword,而具体的剑被标记为内部怎么办?

目前,我使用自制的依赖解析器,我可以说var sword = DependencyResolver.Current.Resolve<ISword>();,它给了我一个剑作为ISword。我的具体类被标记为内部,所以开发人员必须通过我的依赖解析器创建一个实例。 Ninject有类似的东西吗?

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

感谢

回答

13

当你将一个接口绑定到一个具体类型时,你可以询问该接口的一个实例并获得具体的类型。在你的榜样,你可以这样做:

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中,你可以通过使用配置文件来做到这一点,而不是在代码中连接你的依赖关系。 Ninject不幸的是不支持配置文件。

你的替代方案,是使用非泛型重载:

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

然后你应该能够做这样的事情:

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

但是这是一个很大的fugly如果你问我......

相关问题