How to keep IoC container in one place, while inner classes need to create dependencies after beeing constructed

耗尽温柔 提交于 2019-12-10 14:44:06

问题


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 ?


回答1:


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.




回答2:


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




回答3:


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.



来源:https://stackoverflow.com/questions/5489489/how-to-keep-ioc-container-in-one-place-while-inner-classes-need-to-create-depen

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!