使用 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 对象中,我的 IWeapon 自动是一把剑。
这很酷,但是如果我只想要没有武士的 ISword 并且混凝土剑被标记为内部怎么办?
目前,我使用自制的依赖解析器,我可以说 var Sword = DependencyResolver.Current.Resolve
,它给我返回了一个转换为 ISword 的 Sword。我的具体类被标记为内部,因此开发人员必须通过我的依赖解析器来创建实例。 Ninject 有类似的东西吗?
还有一个额外的问题,我用自定义的“DefaultConcreteType”属性装饰我的接口,如果不存在映射,我的依赖解析器可以使用该属性。 Ninject也有类似的东西吗?
谢谢
The samples I've seen so far look like this:
Write your code like this...
public class Samurai {
public IWeapon Weapon { get; private set; }
public Samurai(IWeapon weapon) {
Weapon = weapon;
}
}
And Ninject can map the interface to the concrete type like this...
public class WarriorModule : NinjectModule {
public override void Load() {
Bind<IWeapon>().To<Sword>();
}
}
So when I say var samurai = kernel.Get<Samurai>();
in my Samurai object my IWeapon is automatically a Sword.
That's cool, but what if I want just the ISword without the Samurai and the concrete sword is marked as internal?
Currently, I use a home made dependency resolver where I could say var sword = DependencyResolver.Current.Resolve<ISword>();
and it gives me back a Sword cast as ISword. My concrete classes are marked as internal so the developer must go through my dependency resolver to create an instance. Does Ninject have anything similar to this?
And a bonus question, I decorate my Interfaces with a custom "DefaultConcreteType" attribute which my dependency resolver can use if no mapping exists. Does Ninject have anything like that either?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
将接口绑定到具体类型时,您可以请求该接口的实例并获取具体类型。在您的示例中,您可以这样做:
这将为您提供一个具体的
Sword
对象。您还可以使用绑定系统做更多事情。您甚至可以Bind().ToMethod(MySwordFactory);
并编写一个方法来根据请求上下文获取 Swords。您可以做的另一件事是根据注入的类型更改绑定的工作方式。例如,您可以像这样公开自定义类上的属性:
然后您可以绑定到基于 MyClass 的特定 ISword 实现:
还有更多选项,但这应该为您提供一个粗略的概述。
When you bind an interface to a concrete type, you can ask for an instance of that interface and obtain the concrete type. In your example, you could do this:
And this would give you a concrete
Sword
object. You can do a lot more with the binding system, too. You could evenBind<ISword>().ToMethod(MySwordFactory);
and write a method to get Swords based on the requesting context.Another thing you can do is to change how binding works based on the type it's being injected into. For example, you could expose a property on a custom class like so:
And then you could bind to a specific ISword implementation based on the MyClass:
There are a lot more options, but this should give you a rough overview.
我建议使用可以创建 ISword 的抽象工厂。与
DependencyResolver
相比,它的优势在于它可以创建的类型是有限的(ISword
)。您的抽象工厂需要公开,就像您的 DependencyResolver 一样。
I would recommend using an abstract factory that can create
ISword
s. This has an advantage overDependencyResolver
in that the types it can create are bounded (to beingISword
).Your abstract factory/ies will need to be public, just like your DependencyResolver.
这并不能直接回答您的问题,但我知道使用 Unity,您可以通过使用配置文件来完成此操作,而不是在代码中连接依赖项。不幸的是,Ninject 不支持配置文件。
您的替代方法是使用非泛型重载:
然后您应该能够执行类似的操作:
但如果您问我的话,那就太麻烦了......
This doesn't directly answer your question, but I know with Unity, you can do this by using the Config files as opposed to wiring your dependencies in code. Ninject unfortunately doesn't have support for Config files.
Your alternative to this, is to use the non-generic overloads:
And then you should be able to do something like:
but that's a big fugly if you ask me....