Set Ninject with Web api 6

Topics: Web Api
Feb 8, 2012 at 5:55 AM

Hi,

 

Earlier i was using following code for configuring Ninject Resource factory in global Asax. 
     

var kernel = BuildKernel();
   var config = HttpHostConfiguration.Create().SetOperationHandlerFactory(kernel.Get(typeof(MyOperationHandlerFactory)) as    MyOperationHandlerFactory).SetResourceFactory(new NinjectResourceFactory(kernel)).SetErrorHandler<SecurityServiceErrorHandler>();
                     RouteTable.Routes.MapServiceRoute<SecurityService>("SecurityService", config);
       }
        protected IKernel BuildKernel ()    
        {         IKernel kernel = new StandardKernel ();          // Load up the Kernel         
                 return kernel;    
        }

 

 

Now i am using following:

 

 

var config = new

WebApiConfiguration

 

 

{EnableTestClient =

false

,

CreateInstance = (serviceType, context, reqeust) => BuildKernel().Get(serviceType),RequestHandlers =

new MyOperationHandlerFactory

().RequestHandlerDelegate,

ResponseHandlers =new MyOperationHandlerFactory 

().ResponseHandlerDelegate,ErrorHandlers = (sw, sd, sc) => sw.Add(new SecurityServiceErrorHandler

())

 

};

 

 

 

 

 

 

protected IKernel

BuildKernel ()

{ IKernel kernel = new StandardKernel();

// Load up the Kernel return

kernel;

}

 

 But it does not working .I think i have issue in Create Instance.If any one have any idea about the configuration of Ninject  resource  than please let me know.

 

 Thanks in Adavance

 

Feb 8, 2012 at 6:18 AM

You should not be calling BuildKernel() as part of your CreateInstance.  BuildKernel should be part of your composition root and be maintained throughout the application's life cycle. What's happening is every request comes in, calling your CreateInstance Func<> delegate, thus rebuilding your kernel.  So any registered types with Ninject are no longer there.

Feb 8, 2012 at 6:28 AM
dgdev wrote:

You should not be calling BuildKernel() as part of your CreateInstance.  BuildKernel should be part of your composition root and be maintained throughout the application's life cycle. What's happening is every request comes in, calling your CreateInstance Func<> delegate, thus rebuilding your kernel.  So any registered types with Ninject are no longer there.


It Means there is no need of Creat Instance  here..

var config = new

 

 

 

 

 

};

{EnableTestClient =

false

, RequestHandlers =

new MyOperationHandlerFactory

().RequestHandlerDelegate,

ResponseHandlers =new MyOperationHandlerFactory 

().ResponseHandlerDelegate,ErrorHandlers = (sw, sd, sc) => sw.Add(new SecurityServiceErrorHandler

())

 

 Rihgt  ?

 

 

WebApiConfiguration

Feb 8, 2012 at 7:19 AM

I have this working with structuremap. I'm sure they can't be all that different, so I'll give you my code samples tomorrow. It is a bit late where I am right now. Just an FYI.

Feb 8, 2012 at 8:39 AM

Ninject works well with WCF Web API.  As digitalpacman says, you should create and set up an instance of StandardKernel just once, and then use it when creating all your service types, operation handlers, message handlers (assuming that they need injected dependencies).

I new-up a StandardKernel on application start, bind interfaces to concrete types, and store the kernel instance in a private, static field of my application class.  This one kernel is then used to create instances (e.g. of service types).

For more info see here:- http://stackoverflow.com/questions/7602327/ninject-working-with-wcf-web-api-preview-5 although note that not all the solutions are correct - one of them falls into the trap of creating and setting up a new kernel on each CreateInstance callback.

Feb 8, 2012 at 4:24 PM

 

            CreateInstance = OnCreateInstance;
            ReleaseInstance = OnReleaseInstance;

 
        private object OnCreateInstance(Type type, InstanceContext instanceContext, HttpRequestMessage message)
        {
            // Using nested container will track all transient objects (e.g. non singleton, objects
            // not scoped into httpcontext). When nested container is disposed
            // then all transient objects are also disposed. It will call Dispose() on all
            // objects it has created.
            var nestedContainer = ObjectFactory.Container.GetNestedContainer();
 
            var extension = new NestedContainerExtension(nestedContainer);
            instanceContext.Extensions.Add(extension);
 
            var instance = nestedContainer.GetInstance(type);
 
            return instance;
        }
 
        private void OnReleaseInstance(InstanceContext instanceContext, object instance)
        {
            // The Dispose will dispose the nested container which causes the database session etc.
            // to be disposed correctly. Since SessionFactory is configured as singleton in
            // structuremap registry it is not disposed.
            var extesion = instanceContext.Extensions.Find<NestedContainerExtension>();
            extesion.Dispose();
        }

    public class NestedContainerExtension : IExtension<InstanceContext>, IDisposable
    {
        private readonly IContainer _container;
 
        public NestedContainerExtension(IContainer container)
        {
            _container = container;
        }
 
        public void Attach(InstanceContext owner)
        {
 
        }
 
        public void Detach(InstanceContext owner)
        {
            Dispose();
        }
 
        public void Dispose()
        {
            if (null == _container)
            {
                return;
            }
 
            _container.Dispose();
        }
    }



That is how I did it with StructureMap, hope it helps. Sorry but I do not know ninject very well.