如何使用 Ninject Conventions Extension 进行绑定?
-
23-12-2019 - |
题
我喜欢使用 Ninject 自动绑定来绑定以下代码。是否可以在单个项目中同时使用手动和自动绑定?让我们以手动绑定为例,我想通过自动绑定来实现。请告诉我如何实现这一目标。
kernel.Bind<TestContext>().ToSelf().InRequestScope();
kernel.Bind<IUnitOfWork<TestContext>>().To<UnitOfWork<TestContext>>();
下面是从基本接口继承的所有接口: IRepository<模型>
3 . kernel.Bind<IUserRepository>().To<UserRepository>();
4 . kernel.Bind<IAccountRepository>().To<AccountRepository>();
5 . kernel.Bind<IMessageRepository>().To<MessageRepository>().WithConstructorArgument("apikey", AppSettingsManager.GetSmsApiKey)
额外的
我需要写吗 .Exclude<MessageRepository>()
对于多个课程如果我需要这样做,例如
.Exclude<ARepository>()
.Exclude<BRepository>()
.Exclude<CRepository>()
?
1 和 2 需要单独手动绑定吗?或者 1 可以使用 BindToSelf()' and
.配置(b => b.InRequestScope())` ?
解决方案
是的,可以在同一个项目中,甚至在同一个模块中使用约定绑定和单一绑定。
IBindingRoot.Bind(x => x
.FromThisAssembly()
.IncludingNonePublicTypes()
.SelectAllClasses()
.InheritedFrom(typeof(IRepository<>))
.BindDefaultInterface()
.Configure(y => y.InRequestScope()));
但是,您将无法将构造函数参数传递给特定的类。因此,我建议将构造函数参数替换为包装对配置的访问的接口(无论如何,这是一个很好的设计)。
或者你也可以这样做:
IBindingRoot.Bind(x => x
.FromThisAssembly()
.IncludingNonePublicTypes()
.SelectAllClasses()
.InheritedFrom(typeof(IRepository<>))
.Exclude<MessageRepository>()
.BindDefaultInterface()
.Configure(y => y.InRequestScope()));
IBindingRoot.Bind<IMessageRepository>().To<MessageRepository>)
.WithConstructorArgument("apikey", AppSettingsManager.GetSmsApiKey)
.InRequestScope();
--> 你可以做一个 .Exclude<TRepository>()
对于每个存储库,其中约定绑定是不够的。对于每一个排除的绑定,您都必须自己指定一个。如上:所有实现类的条件绑定 IRepository<>
除了 班级 MessageRepository
, ,它有自己的绑定。
另请看一下这个:https://github.com/ninject/ninject.extensions.conventions/wiki/Projecting-Services-to-Bind
附录:请注意,您可以指定多个常规绑定,例如:
IBindingRoot.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom(typeof(IFoo))
.BindDefaultInterface()
.Configure(y => y.InRequestScope()));
IBindingRoot.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.InheritedFrom(typeof(IBar))
.BindToSelf()
.Configure(y => y.InRequestScope()));
完全没问题。
其他提示
如果您只有少量异常,以前的解决方案就会有效。如果有更多的话,你将最终得到很多没有意义的惯例。
使用ibindingroot.rebind方法覆盖与已经被惯例所涵盖的绑定重叠。
IBindingRoot.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.BindAllInterface());
IBindingRoot.Rebind<IMessageRepository>().To<MessageRepository>)
.WithConstructorArgument("apikey", AppSettingsManager.GetSmsApiKey)
.InRequestScope();
.