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

发布于 2024-10-22 05:40:52 字数 847 浏览 6 评论 0原文

到目前为止我看到的示例如下所示:

像这样编写代码...

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

终难愈 2024-10-29 05:40:52

将接口绑定到具体类型时,您可以请求该接口的实例并获取具体类型。在您的示例中,您可以这样做:

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

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

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

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

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

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

还有更多选项,但这应该为您提供一个粗略的概述。

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:

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

And this would give you a concrete Sword object. You can do a lot more with the binding system, too. You could even Bind<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:

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

And then you could bind to a specific ISword implementation based on the MyClass:

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

There are a lot more options, but this should give you a rough overview.

冷…雨湿花 2024-10-29 05:40:52

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

您的抽象工厂需要公开,就像您的 DependencyResolver 一样。

I would recommend using an abstract factory that can create ISwords. This has an advantage over DependencyResolver in that the types it can create are bounded (to being ISword).

Your abstract factory/ies will need to be public, just like your DependencyResolver.

∝单色的世界 2024-10-29 05:40:52

这并不能直接回答您的问题,但我知道使用 Unity,您可以通过使用配置文件来完成此操作,而不是在代码中连接依赖项。不幸的是,Ninject 不支持配置文件。

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

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

然后您应该能够执行类似的操作:

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

但如果您问我的话,那就太麻烦了......

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:

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

And then you should be able to do something like:

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

but that's a big fugly if you ask me....

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文