问题
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 ?
回答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:
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
回答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