如何将 IoC 容器保留在一处,而内部类在构建后需要创建依赖项
我开始在这个相对较小的项目上使用 Ninject ,我遇到了一个问题:我有一个
class SomeService : ISomeService
依赖于
class BizLogicModule : IBizLogicModule
该类的类,而该类又依赖于
class DataRepository : IDataRepository
DataRepository
有一个看起来像这样的 ctor:
DataRepository(BizEntityModel context)
现在,我需要能够在多个 IDataRepository
实例中使用单个 BizEntityModel
实例。
我还需要在 IBizLogicModule
的生命周期中创建 IDataRepository
。 IBizLogicModule
不了解 Ninject,我想保持这种状态。
所以我的问题是: 如何使用 Ninject 内核将所有这些连接起来,同时:
不必在层周围传递内核实例。
让代码的可读性接近之前的 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:
not having to pass the kernel instance around the layers.
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我重复这个问题,就像我理解的那样:
每个 BizLogicModule 实例都存在一个 BizEntityModel 实例(它们没有相互引用)
每当 BizLogicModule 创建 DataRepository 时,都会重用此 BizEntityModel
有多个 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:
Exactly one BizEntityModel instance exists per BizLogicModule instance (They do not have a reference to each other)
Whenever BizLogicModule creates a DataRepository this BizEntityModel is reused
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
您是否向 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 oneIBizLogicModule
. 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 onlyIDataRepositoryFactory
dependency.