Frage

Ich binde den folgenden Code gerne mit der automatischen Ninject-Bindung.Ist es möglich, innerhalb eines einzigen Projekts sowohl die manuelle als auch die automatische Bindung zu verwenden?Nehmen wir die folgende manuelle Bindung, die ich mit der automatischen Bindung erreichen möchte.Bitte sagen Sie mir, wie ich das erreichen kann.

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

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

Im Folgenden werden alle von der Basisschnittstelle geerbten Schnittstellen aufgeführt: IRepository< Modell >

3 . kernel.Bind<IUserRepository>().To<UserRepository>();

4 . kernel.Bind<IAccountRepository>().To<AccountRepository>();

5 . kernel.Bind<IMessageRepository>().To<MessageRepository>().WithConstructorArgument("apikey", AppSettingsManager.GetSmsApiKey)

Zusätzlich

Muss ich schreiben? .Exclude<MessageRepository>() für mehrere Klassen Wenn ich es tun muss, z

.Exclude<ARepository>() .Exclude<BRepository>() .Exclude<CRepository>() ?

und ist für 1 und 2 eine separate manuelle Bindung erforderlich?oder 1 kann mit erfolgen BindToSelf()' and.Configure(b => b.InRequestScope())` ?

War es hilfreich?

Lösung

Ja, es ist möglich, Konventionsbindung und Einzelbindung im selben Projekt zu verwenden, sogar im selben Modul.

IBindingRoot.Bind(x => x
    .FromThisAssembly()
    .IncludingNonePublicTypes()
    .SelectAllClasses()
    .InheritedFrom(typeof(IRepository<>))
    .BindDefaultInterface()
    .Configure(y => y.InRequestScope()));

Sie können jedoch kein Konstruktorargument an eine bestimmte Klasse übergeben.Daher schlage ich vor, das Konstruktorargument durch eine Schnittstelle zu ersetzen, die den Zugriff auf die Konfiguration umschließt (das ist jedenfalls ein schönes Design).

Alternativ können Sie auch Folgendes tun:

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

-> Du kannst eins machen .Exclude<TRepository>() für jedes Repository, bei dem die Konventionsbindung nicht ausreicht.Für jede ausgeschlossene Bindung müssen Sie selbst eine angeben.Wie oben:Bedingte Bindung für alle implementierenden Klassen IRepository<> außer Klasse MessageRepository, das eine eigene Bindung erhält.

Schauen Sie sich auch das hier an:https://github.com/ninject/ninject.extensions.conventions/wiki/Projecting-Services-to-Bind

Nachtrag:Beachten Sie, dass Sie mehrere herkömmliche Bindungen angeben können, zum Beispiel:

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

Ist völlig ok.

Andere Tipps

Die vorherige Lösung funktioniert, wenn Sie nur wenige Ausnahmen haben.Wenn es mehr davon gibt, ergibt sich eine Menge Konventionen, die keinen Sinn ergeben.

Verwenden Sie die IBindingRoot.Rebind-Methode, um Bindungen zu überschreiben, die sich mit der Bindung überschneiden, die bereits von der Konvention abgedeckt wird.

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

IBindingRoot.Rebind<IMessageRepository>().To<MessageRepository>)
.WithConstructorArgument("apikey", AppSettingsManager.GetSmsApiKey)
.InRequestScope();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top