I am trying to make something like an IAuditable
interface, which acts as a marker for Ninject to intercept calls to.
Suppose I have the following:
public interface IAuditable
{
}
public interface IProcessor
{
void Process(object o);
}
public class Processor : IProcessor, IAuditable
{
public void Process(object o)
{
Console.WriteLine("Processor called with argument " + o.ToString());
}
}
With this setup:
NinjectSettings settings = new NinjectSettings() { LoadExtensions = true };
IKernel kernel = new StandardKernel(settings);
kernel.Bind<IAuditAggregator>().To<AuditAggregator>().InThreadScope();
kernel.Bind<IAuditInterceptor>().To<AuditInterceptor>();
kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<IAuditable>()
.BindToDefaultInterfaces() //I suspect I need something else here
.Configure(c => c.Intercept().With<IAuditInterceptor>()));
kernel.Bind<IProcessor>().To<Processor>();
Whenever I try to kernel.Get<IProcessor>();
I get an exception telling me there are multiple bindings available.
If I remove kernel.Bind<IProcessor>().To<Processor>()
then it works as expected, but it is possible that you can have an IProcessor
that does not implement IAuditable
.
Am I on the right track?
Edit: As suggested I tried using an attribute instead:
public class AuditableAttribute : Attribute
{
}
[Auditable]
public class Processor : IProcessor
{
public void Process(object o)
{
Console.WriteLine("Processor called with argument " + o.ToString());
}
}
//in setup:
kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.WithAttribute<AuditableAttribute>()
.BindDefaultInterface()
.Configure(c => c.Intercept().With<IAuditInterceptor>()));
This results in the same duplicate binding issue as with using an interface instead.
You should be able to write one convention binding for types implementing IAuditable and one for types not implementing.
kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<IAuditable>()
.BindDefaultInterfaces()
.Configure(c => c.Intercept().With<IAuditInterceptor>()));
kernel.Bind(x =>
x.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom<IProcessor>()
.Where(t => !typeof(IAuditable).IsAssignableFrom(t))
.BindDefaultInterfaces());