How to bind using Ninject Conventions Extension?

≡放荡痞女 提交于 2019-12-22 12:24:08

问题


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.

  1. kernel.Bind<TestContext>().ToSelf().InRequestScope();

  2. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!