Как выполнить привязку с помощью расширения Ninject Conventions?

Мне нравится связывать приведенный ниже код с автоматической привязкой Ninject. Можно ли использовать как ручную, так и автоматическую привязку в одном проекте? Давайте возьмем ниже ручную привязку, которую я хочу добиться с помощью автоматической привязки. Пожалуйста, скажите мне, как этого добиться.

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

  2. kernel.Bind<IUnitOfWork<TestContext>>().To<UnitOfWork<TestContext>>();

Ниже приведены все интерфейсы, унаследованные от базового интерфейса: IRepository‹ Model >

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.Configure(b => b.InRequestScope())` ?


person Shubhajyoti Ghosh    schedule 27.02.2014    source источник
comment
Для 1. и 2. вы должны использовать отдельную привязку. Теоретически вы можете использовать соглашения и сказать ему привязать все классы во всей сборке к его интерфейсу по умолчанию, но в среднесрочной и долгосрочной перспективе это вызовет больше сложностей, чем указание конкретных сингулярных привязок. Также обратите внимание, что вы можете использовать несколько обычных креплений!   -  person BatteryBackupUnit    schedule 28.02.2014


Ответы (2)


Да, можно использовать привязку по соглашению и одиночную привязку в одном проекте, даже в одном модуле.

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()));

Полностью в порядке.

person BatteryBackupUnit    schedule 27.02.2014
comment
спасибо за ваш ответ, я просто расширяю свои вопросы, не могли бы вы проверить. - person Shubhajyoti Ghosh; 27.02.2014

Предыдущее решение работает, если у вас всего несколько исключений. Если их больше, вы получите множество соглашений, которые не имеют смысла.

Используйте метод IBindingRoot.Rebind, чтобы переопределить привязки, которые перекрываются с привязкой, уже охваченной соглашением.

IBindingRoot.Bind(x => x
.FromThisAssembly()
.SelectAllClasses()
.BindAllInterface());

IBindingRoot.Rebind<IMessageRepository>().To<MessageRepository>)
.WithConstructorArgument("apikey", AppSettingsManager.GetSmsApiKey)
.InRequestScope();
person Daniel    schedule 05.11.2015