4

I'm running into what looks like a bug using Ninject 3 with an MVC WebAPI / Windows Azure project. I have a repository object that looks something like this:

public class Repository : IRepository
{
    /// <summary>
    /// Initialize a new repository object.
    /// </summary>
    public Repository(
        CloudStorageAccount storageAccount,
        ISerializer serializer,
        int timeoutMS = 30000,
        string activityLogQueueName = "activitylog",
        string fileStageName = "filestage",
        string blobTrackingTableName = "blobtracking")
    {
        //snipped boring stuff
    }
 }

And in NinjecWebCommon I have bindings like so:

kernel.Bind<Data.IRepository>().To<Data.Repository>();
kernel.Bind<Data.ISerializer>().To<Data.Serializer>();

kernel.Bind<Microsoft.WindowsAzure.Storage.CloudStorageAccount>().ToMethod((context) =>
{
    //code to get storage account from azure config
}

As the repository initializes, it uses the strings for activityLogQueueName etc to create any missing containers and setup Azure client objects. This all works fine - the problem is that Ninject is somehow taking the value of the first string parameter ("activityLog") and passing it to all the string parameters, so my blob container and tracking table end up named "activityLog" as well.

If I specify those parameters in the binding like this:

kernel.Bind<Data.IRepository>().To<Data.Repository>().WithConstructorArgument("fileStageName", "filestage");

everything works, so I'm confident it's not a bug in my code.

Here's the resolver I'm using:

public class NinjectResolver : NinjectScope, IDependencyResolver
{
    private IKernel _kernel;
    public NinjectResolver(IKernel kernel)
        : base(kernel)
    {
        _kernel = kernel;
    }
    public IDependencyScope BeginScope()
    {
        return new NinjectScope(_kernel.BeginBlock());
    }
}

And the scope:

public class NinjectScope : IDependencyScope
{
    protected IResolutionRoot resolutionRoot;

    public NinjectScope(IResolutionRoot kernel)
    {
        resolutionRoot = kernel;
    }

    public object GetService(Type serviceType)
    {
        IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
        return resolutionRoot.Resolve(request).SingleOrDefault();
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
        return resolutionRoot.Resolve(request).ToList();
    }

    public void Dispose()
    {
        IDisposable disposable = (IDisposable)resolutionRoot;
        if (disposable != null) disposable.Dispose();
        resolutionRoot = null;
    }
}

Otherwise everything is as delivered via nuget.

superstator
  • 3,005
  • 1
  • 33
  • 43
  • 1
    So far, I can tell that this is related to the `IActivactionBlock` returned by `kernel.BeginBlock()`. I have reproduced your code just using the default `kernel.Get()` and it works fine. However, o managed to reproduce it if I use `kernel.BeginBlock().Get`. I'm investigating Ninject code to see if I can help pinpoint the cause. – cvbarros Jan 23 '14 at 20:55
  • Great, thanks! I have a workaround for now, but I wanted to flag it. – superstator Jan 23 '14 at 22:38

0 Answers0