如何将 IoC 容器保留在一处,而内部类在构建后需要创建依赖项

发布于 2024-10-28 01:43:15 字数 1533 浏览 6 评论 0原文

我开始在这个相对较小的项目上使用 Ninject ,我遇到了一个问题:我有一个

class SomeService : ISomeService 

依赖于

class BizLogicModule : IBizLogicModule

该类的类,而该类又依赖于

class DataRepository : IDataRepository

DataRepository 有一个看起来像这样的 ctor:

DataRepository(BizEntityModel context)

现在,我需要能够在多个 IDataRepository 实例中使用单个 BizEntityModel 实例。
我还需要在 IBizLogicModule 的生命周期中创建 IDataRepositoryIBizLogicModule 不了解 Ninject,我想保持这种状态。

所以我的问题是: 如何使用 Ninject 内核将所有这些连接起来,同时:

  1. 不必在层周围传递内核实例。

  2. 让代码的可读性接近之前的 Ninject(我刚刚使用工厂方法)。

到目前为止,我得到的接线的简单部分是:

Bind<SomeService>().To<ISomeService>();
Bind<BizLogicModule>().To<IBizLogicModule>();
Bind<DataRepository>().To<IDataRepository>(); 
Bind<BizEntityModel>().To<BizEntityModel>(); //ToSelf()
// .WithConstructorArgument(context => Kernel.Get<BizEntityModel>)

非常感谢您的指导

编辑:感谢您的回答!
以下是所请求的更多数据: BizEntityModel 已向 Ninject 注册(代码已更新)。

如果我理解正确的话:我可以使用“工厂方法”在 IBizLogicModule 中创建 IDataRepository 的实例。但这给我留下了:
1) 我需要将 BizEntityModel 传递给工厂方法,有时是全新的,有时是现有的实例。使用工厂方法,每次都会重新创建一个。
2) 这是 SomeService 位于另一个程序集中的问题,并且只有它具有对 Ninject.dll 的引用吗?

I started to use Ninject , on this relatively small project and i have run into a problem: i have this class

class SomeService : ISomeService 

that depends on

class BizLogicModule : IBizLogicModule

that in turn depends on

class DataRepository : IDataRepository

the DataRepository has a ctor that looks like:

DataRepository(BizEntityModel context)

Now, i need to be able to use a single instance of BizEntityModel across more than one IDataRepository instance.
I also need to create IDataRepository's along the life of a IBizLogicModule. The IBizLogicModule does not know about Ninject and i want to keep it that way.

so my problem is:
how to wire all that up, using the Ninject kernel, while:

  1. not having to pass the kernel instance around the layers.

  2. leaving the code readable close to what it was prior Ninject (i was just new'ing using a factory method).

The simple part of the wiring i got so far is:

Bind<SomeService>().To<ISomeService>();
Bind<BizLogicModule>().To<IBizLogicModule>();
Bind<DataRepository>().To<IDataRepository>(); 
Bind<BizEntityModel>().To<BizEntityModel>(); //ToSelf()
// .WithConstructorArgument(context => Kernel.Get<BizEntityModel>)

Your guidance is very much appreciated

EDIT: Thanks for your answers!
here's some more data that was requested:
BizEntityModel is registered with Ninject (code updated).

if i understand correctly: i can create instances of IDataRepository in IBizLogicModule using a 'factory method'. but that leaves me with:
1) i need to pass a BizEntityModel to the factory method, some times its bran new and sometimes its an existing instance. using the factory method, it will create anew one every time.
2) is this a problem that SomeService is in another assembly, and only it has a ref to Ninject.dll ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

海的爱人是光 2024-11-04 01:43:15

我重复这个问题,就像我理解的那样:

  1. 每个 BizLogicModule 实例都存在一个 BizEntityModel 实例(它们没有相互引用)

  2. 每当 BizLogicModule 创建 DataRepository 时,都会重用此 BizEntityModel

  3. 有多个 BizLogicModule

如果这是正确的,则NamedScope 扩展文档中的第二个示例应该适合您。请参阅 https://github.com/ninject/ninject.extensions.namedscope/wiki/ InNamedScope

确保您阅读了此扩展的完整文档:https:// github.com/ninject/ninject.extensions.namedscope/wiki

I repeat the question a like I understood it:

  1. Exactly one BizEntityModel instance exists per BizLogicModule instance (They do not have a reference to each other)

  2. Whenever BizLogicModule creates a DataRepository this BizEntityModel is reused

  3. There are several BizLogicModules

If this is correct the second example in the NamedScope extension documentation should fit for you. See https://github.com/ninject/ninject.extensions.namedscope/wiki/InNamedScope

Make sure that you read the complete docu of this extension: https://github.com/ninject/ninject.extensions.namedscope/wiki

难理解 2024-11-04 01:43:15

您是否向 Ninject 注册了 BizEntityModel?如果是这样,您应该能够告诉 Ninject 在容器甚至程序的生命周期内为每个请求提供一个且仅一个 BizEntityModel 实例,而无需定义和注册 BizEntityModel 的传统单例实例。即使您必须使用工厂方法,并且 Ninject 不允许您将注册范围设置为单例,但如果您必须这样做,您也可以急切加载该对象,然后将依赖项的实例注册为单例。

IBizLogicModule 永远不必了解 Ninject; Ninject 应该了解 BizLogicModule。尝试创建一个 IDataRepository 注册,该注册将提供一个工厂方法(工厂范围,因此每次调用都会创建一个新实例),然后将该工厂方法作为依赖项传递给 IBizLogicModule,IBizLogicModule 将在需要创建 IDataRepositories 时使用它。您基本上是通过 IoC 的解析功能在 IBizLogicModule 中提供工厂类。如果您对 IBizLogicModule 上的许多不同类类型执行此操作,那么您基本上是在创建一个我个人会避免的服务定位器,但其中一两个是完全有效的工厂/创建者模式。

Do you register BizEntityModel with Ninject? If so, you should be able to tell Ninject to supply one and only one instance of a BizEntityModel for every request for the lifetime of the container, or even the program, without having to define and register a traditional singleton instance of BizEntityModel. Even if you have to work with a factory method and Ninject won't let you singleton-scope that registraion, if you have to you can eager-load the object and then register the instance for the dependency as a singleton.

IBizLogicModule should never have to know about Ninject; Ninject should know about BizLogicModule. Try creating an IDataRepository registration that will provide a factory method (factory-scoped so a new instance is created per call), then pass that factory method as a dependency to IBizLogicModule, which will use it when it needs to create IDataRepositories. You're basically passing through the IoC's resolution capabilities to provide a factory class in IBizLogicModule. If you do that for a lot of different class types on IBizLogicModule, you're basically creating a service locator which I would personally avoid, but one or two is a perfectly valid Factory/Creator pattern.

下面的答案假设您询问如何解析一个 IBizLogicModule 中的多个 IDataRepository 实例。否则这个问题就太简单了:-)

通常好的 IoC 容器有能力注入工厂/工厂方法。我对 NInject 没有太多经验,也没有找到像其他容器那样好的解决方案,但 在这里您可以看到如何实现主要任务的示例。这里唯一的问题是,您必须自己实现一个工厂并将 IResolutionContext 拉到那里,但无论如何,这个工厂将允许您将其余代码 (IBizLogicModule) 与IoC 细节,因为它只有 IDataRepositoryFactory 依赖项。

The answer below assumes that you're asking how to resolve many instances of IDataRepository in one IBizLogicModule. Otherwise this question will be too easy :-)

Usually good IoC containers have an ability to inject Factories/Factory methods. I do not have much experience with NInject and I haven't found as good solutions as I know for other containers but HERE you can see example how the main task can be achieved. The only issue here is that you will have to implement a factory on your own and pull IResolutionContext there but anyway this factory will allow you isolating rest of your code (IBizLogicModule) from IoC specifics because it will have only IDataRepositoryFactory dependency.

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