【发布时间】:2017-08-04 13:37:49
【问题描述】:
我正在尝试制作类似IAuditable 接口的东西,它充当 Ninject 拦截调用的标记。
假设我有以下:
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());
}
}
使用此设置:
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>();
每当我尝试kernel.Get<IProcessor>(); 时,我都会收到一个异常,告诉我有多个绑定可用。
如果我删除 kernel.Bind<IProcessor>().To<Processor>(),那么它会按预期工作,但您可能拥有一个未实现 IAuditable 的 IProcessor。
我走对了吗?
编辑:按照建议,我尝试使用属性:
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>()));
这会导致与使用接口相同的重复绑定问题。
【问题讨论】:
-
我认为在这种情况下使用 [Auditable] 属性比使用标记接口更好。
-
我想您可以在
Configurelambda 中编写一个条件语句,仅当类型实现接口(或标记有属性)时才调用Intercept()。 -
使用属性会产生相同的结果,会创建一个重复的绑定。
-
顺便说一句,关于
InThreadScope的使用:stackoverflow.com/a/14592419/264697 -
我不确定我是否理解您的问题。您正在使用
SelectAllClasses,由于标记接口或属性,它有效地拾取Processor。然后你“手动”在底部添加另一个绑定,所以它当然会抱怨。
标签: c# ninject interceptor convention ninject-interception