5

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 ?

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
Menahem
  • 3,974
  • 1
  • 28
  • 43
  • 1
    What rule has this sometimes new, sometimes reused? – Remo Gloor Mar 30 '11 at 19:16
  • i am using a 'unit of work' style with the repository, sometimes making more than one change and saving them in a transaction. in simple cases i juts use an instance for just one change. (not sure i answered what the rule is since its the logic itself) – Menahem Mar 31 '11 at 08:32

3 Answers3

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

Remo Gloor
  • 32,665
  • 4
  • 68
  • 98
  • hi ,just to explain myself better, the first assumption is not correct. there may be more than one `BizEntityModel` in a `BizLogicModule `, and sometimes one instance will be used more than once. – Menahem Mar 30 '11 at 18:52
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.

KeithS
  • 70,210
  • 21
  • 112
  • 164
  • after re reading what you said few times , i think i understand what can be done, so i marked as 'answer'. thank you. – Menahem Mar 31 '11 at 08:52
0

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.

Snowbear
  • 16,924
  • 3
  • 43
  • 67
  • your assumption is correct , but i also need to supply an argument to the factory. (that argument is a `BizEntityModel` that i may have hanging around, rather that a new one). i updated the question to better reflect that, can you take a look ? – Menahem Mar 30 '11 at 18:41