问题
I like to bind bellow code with Ninject auto binding. Is it possible to use both mannual & auto binding within a single project? Let;s take bellow manual binding, I want to achieve with auto binding. Please tell me how to achieve this.
kernel.Bind<TestContext>().ToSelf().InRequestScope();
kernel.Bind<IUnitOfWork<TestContext>>().To<UnitOfWork<TestContext>>();
Bellow all interface inherited from base Interface : IRepository< Model >
3 . kernel.Bind<IUserRepository>().To<UserRepository>();
4 . kernel.Bind<IAccountRepository>().To<AccountRepository>();
5 . kernel.Bind<IMessageRepository>().To<MessageRepository>().WithConstructorArgument("apikey", AppSettingsManager.GetSmsApiKey)
Additional
Do I need to write .Exclude<MessageRepository>()
for multiple classes If I required to do it such as
.Exclude<ARepository>()
.Exclude<BRepository>()
.Exclude<CRepository>()
?
and for 1 & 2 is required separate manual binding ? or 1 can be done using BindToSelf()' and
.Configure(b => b.InRequestScope())` ?
回答1:
Yes, it is possible to use convention binding and single binding in the same project, even in the same module.
IBindingRoot.Bind(x => x
.FromThisAssembly()
.IncludingNonePublicTypes()
.SelectAllClasses()
.InheritedFrom(typeof(IRepository<>))
.BindDefaultInterface()
.Configure(y => y.InRequestScope()));
However you won't be able to pass a constructor argument to a specific class. So i suggest replacing the constructor argument with an interface which wraps the access to the configuration (that's a nice design anyway).
Alternatively you can also do this:
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();
--> You can do one .Exclude<TRepository>()
for every repository, where the convention binding is not sufficient. For every exlucded binding you will have to specifiy one yourself. As above: conditional binding for all classes implementing IRepository<>
except class MessageRepository
, which gets its own binding.
Also have a look at this: https://github.com/ninject/ninject.extensions.conventions/wiki/Projecting-Services-to-Bind
Addendum: Note that you can specify multiple conventional bindings, for example:
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()));
Is totally ok.
回答2:
The previous solution works if you have only few number of exceptions. If there are more of them you will end up with a lot of conventions which doesn't make sense.
Use IBindingRoot.Rebind method to override bindings that overlap with the one already covered by the convention.
IBindingRoot.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.BindAllInterface());
IBindingRoot.Rebind<IMessageRepository>().To<MessageRepository>)
.WithConstructorArgument("apikey", AppSettingsManager.GetSmsApiKey)
.InRequestScope();
来源:https://stackoverflow.com/questions/22075389/how-to-bind-using-ninject-conventions-extension