Ninject bug resolving constructor with multiple string parameters

190 views Asked by At

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.

0

There are 0 answers