Post-initialization object creation with ninject
Asked Answered
C

2

5

I'm new to Ninject (and DI in general).

I understand how the kernel loads modules, and the code I've written thus far tends to have a single line:

myKernel.Get<MyApp>()

which constructs everything I need from the bindings in my module. If there's a requirement for new instances post initialization, these are taken care of by factories that I bind for initialization. Up to now, the factories have been free of any ninject dependencies, simply newing up objects on demand.

Now I have reached a point that I need to think about object creation after initialization and my own factory pattern is not cutting it any more. This would be to support a pub/sub interface for (remote) clients. With every new connection to my server, I would like to create new IClient instances according to a set of bindings defined in a ninject module. Does this mean that the factory I pass in at initialization has to have its own kernel (or a ref to the main kernel)? Where would CommonServiceLocator feature in this. Is CSL necessary?

Before I travel too far down dead-ends, I thought it would be best to ask here about how others might approach this problem.

Chatterton answered 22/11, 2011 at 12:58 Comment(0)
B
6

Create a factory interface

public interface IClientFactory
{
    IClient CreateClient();
}

For Ninject 2.3 see https://github.com/ninject/ninject.extensions.factory and let it be implemented by Ninject by adding the following configuration.

Bind<IClientFactory>().ToFactory();

For 2.2 do the implementation yourself. This implementation is part of the container configuration and not part of your implementations.

public class ClientFactory: IClientFactory
{
    private IKernel kernel;
    public ClientFactory(IKernel kernel)
    {
        this.kernel = kernel;
    }

    public IClient CreateClient()
    {
        return this.kernel.Get<IClient>();
    }
}
Boatswain answered 22/11, 2011 at 15:32 Comment(4)
Thanks Remo. So if I understand correctly, in 2.3 you don't need to worry about creating a concrete implementation of the factory interface? The actual implementation is emitted somehow by ninject when bound using a ToFactory() call?Chatterton
Yes its implemented automatically using dynamic proxyBoatswain
Nice. Thanks for your help. It clears up a lot of questions in my head.Chatterton
Remo, can you confirm that it's actually Ninject.Extensions.Factory.BindToExtensions.ToFactory rather than AsFactory, or have I lost my way?Chatterton
C
1

It looks like the following pattern for factory might satisfy my requirements:

Bind<Func<IClient>>().ToMethod(ctx => () => ctx.Kernel.Get<ClientImpl>());

where I have constructor of the form:

SomeCtor(Func<IClient> clientFactory, blah...)
Chatterton answered 22/11, 2011 at 14:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.