7

So I've been playing around with the latest release of the WCF Web API and decided I wanted to dive into implementing Ninject with it.

Based off what I've read I need to implement the interface IResourceFactory which demands the following methods:

    public object GetInstance(System.Type serviceType, 
                              System.ServiceModel.InstanceContext instanceContext,
                              System.Net.Http.HttpRequestMessage request);

    public void ReleaseInstance(System.ServiceModel.InstanceContext instanceContext,
                                object service);

So I chicken scratched the following out:

public class NinjectResourceFactory : IResourceFactory
{
    private readonly IKernel _kernel;

    public NinjectResourceFactory()
    {
        var modules = new INinjectModule[]
                          {
                              new ServiceDIModule(),    //Service Layer Module
                              new RepositoryDIModule(), //Repo Layer Module
                              new DataServiceDIModule()
                          };

        _kernel = new StandardKernel(modules);
    }

    #region IResourceFactory Members

    public object GetInstance(Type serviceType,
                              InstanceContext instanceContext,
                              HttpRequestMessage request)
    {
        return Resolve(serviceType);
    }

    public void ReleaseInstance(InstanceContext instanceContext, object service)
    {
        throw new NotImplementedException();
    }

    #endregion

    private object Resolve(Type type)
    {
        return _kernel.Get(type);
    }

    //private T Resolve<T>()
    //{
    //    return _kernel.Get<T>();
    //}

    //private T Resolve<T>(string name)
    //{
    //    return _kernel.Get<T>(metaData => metaData.Has(name));
    //    return _kernel.Get<T>().Equals(With.Parameters.
    //                                   ContextVariable("name", name));
    //}
}

and wired it up with

var configuration = HttpHostConfiguration.Create().SetResourceFactory(new NinjectResourceFactory());
     RouteTable.Routes.MapServiceRoute<StateProvinceResource>("States", configuration);

Amazingly, this seems to work. The first resource method I created to serve out a list of states/provinces generates output with HTTP 200 OK.

So, to the question. Is there a cleaner way of writing this factory? I really fuddled through it and it just doesn't feel right. I feel like I'm missing something obvious staring me in the face. The hack I made in the new Resolve method feels especially dirty so I figured I'd tap into those more experienced to tighten this up. Has anyone else implemented Ninject with the WCF Web API and implemented a cleaner solution?

Thanks for any input!

Alexander Zeitler
  • 11,919
  • 11
  • 81
  • 124
Khepri
  • 9,547
  • 5
  • 45
  • 61
  • this looks relatively similar to something i've done with structuremap. passing around objects always feels a little hacky, but if its what the framework gives you, what choice is there, besides rolling your own of course. – nathan gonzalez May 06 '11 at 02:44

1 Answers1

0

You could implement it by passing in the Kernel from the application scope.

public class NinjectResourceFactory : IResourceFactory
{
    private readonly IKernel _kernel;

    public NinjectResourceFactory(IKernel kernel)
    {
        _kernel = kernel;
    }

    public object GetInstance(Type serviceType, InstanceContext instanceContext, HttpRequestMessage request)
    {
        return _kernel.Get(serviceType);
    }

    public void ReleaseInstance(InstanceContext instanceContext, object service)
    {
        // no op
    }
}
Jonathan
  • 5,953
  • 1
  • 26
  • 35
  • Yes, that cleans up the factory a fair bit. The part I was really trying to zero in on was the Resolve method being cornered into returning an object instead of a typed result, but I guess this implementation will have to do until/if the Microsoft team modifies the return value. – Khepri May 06 '11 at 15:50
  • Where does the IResourceFactory come from? Is this a Web API interface? I am trying to get this to work with Preview 5 of the Web API without any luck? Did you use the Ninject.MVC or WCF extensions or both? Thanks. – Cragly Sep 30 '11 at 07:28
  • @Cragly this answer was for Preview 3 I think, not applicable to Preview 5 – Jonathan Oct 03 '11 at 23:48