Reputation: 3725
I am trying to implement the Ninject.Extensions.Factory pattern and my program is telling me my bindings aren't right, but I can't figure out why. I keep getting an "Error activating IHashable. No matching bindings are available, and the type is not self-bindable" exception thrown. The relevant areas of my code are below:
public interface IHashable
{
FileInfo File { get; }
string ComputeHash();
}
public interface IHashableFactory
{
IHashable GetNew(FileInfo file);
}
public class MD5ChecksumProvider : IHashable
{
private FileInfo _file;
public FileInfo File
{
get { return _file; }
}
public MD5ChecksumProvider(FileInfo file)
{
if (file == null)
throw new ArgumentNullException("file");
_file = file;
}
public string ComputeHash()
{
// implementation
}
}
public class AppFileProvider : IAppFileProvider
{
private IHashableFactory _hashFactory;
public IHashableFactory HashProvider
{
get { return _hashFactory; }
}
public AppFileProvider(IHashableFactory hashProviderFactory)
{
_hashFactory = hashProviderFactory;
}
public string GetChecksum(FileInfo fileInfo)
{
var hasher = _hashFactory.GetNew(fileInfo);
return hasher.ComputeHash();
}
}
public class BindingProviders : NinjectModule
{
public override void Load()
{
Bind<IHashable>()
.To<MD5ChecksumProvider>();
}
}
public class BindingFactories : NinjectModule
{
public override void Load()
{
Bind<IHashableFactory>()
.ToFactory();
}
}
// my DI container
public sealed class Container : IDisposable
{
private bool _isDisposed;
private IKernel _kernel;
private BindingFactories _bindingFactories;
private BindingObjects _bindingObjects;
private BindingProviders _bindingProviders;
public Container()
{
_isDisposed = false;
_bindingFactories = new BindingFactories();
_bindingObjects = new BindingObjects();
_bindingProviders = new BindingProviders();
_kernel = new StandardKernel(_bindingObjects, _bindingProviders, _bindingFactories);
}
public T Get<T>()
{
return _kernel.Get<T>();
}
public void Dispose()
{
// nothing worth seeing
}
private void Dispose(bool disposing)
{
// nothing worth seeing
}
}
// the program (composition root)
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
using (var container = new Container())
{
var fileProvider = container.Get<IAppFileProvider>();
foreach (var file in files)
{
string hash = fileProvider.GetChecksum(storePath, file); // this line throws "Error activating IHashable. No matching bindings are available, and the type is not self-bindable.""
}
}
}
}
I feel like my bindings are setup correctly but I must be missing something obvious. Any ideas why I'm getting the exception from the above code?
Upvotes: 3
Views: 1132
Reputation: 13233
This is caused by a feature of Ninject.Extensions.Factory.
It treats methods which start with Get
differently from those which don't.
If you rename IHashableFactory.GetNew
to Create
or Make
everything works fine.
The "Get
" feature is described here:
The default instace provider of the extension has the convention that it tries to return an instance using a named binding whenever a method starts with “Get”. E.g. IFoo GetMySpecialFoo() is equal to
resolutionRoot.Get<IFoo>("MySpecialFoo");
Since i think this is not obvious to the user and the exception isn't helpful at all in this regard, i have filed an issue report here
Upvotes: 3