2009-06-22 10 views
2

Ich schreibe gerade ein Open Source-SDK für ein Programm, das ich verwende, und ich verwende intern einen IoC-Container (NInject), um alle meine internen Abhängigkeiten zu verdrahten.Verwenden von IoC mit internen Objekten

Ich habe einige Objekte, die als intern markiert sind, so dass ich nicht die öffentliche API drängen, da sie nur intern verwendet werden und vom Benutzer nicht gesehen werden sollten, wie Fabriken und andere Objekte. Das Problem, das ich habe, ist, dass NInject interne Objekte nicht erstellen kann, was bedeutet, dass ich alle meine internen Objekte öffentlich markieren muss, die die öffentliche API überladen.

Meine Frage ist: Gibt es eine Möglichkeit, um dieses Problem zu umgehen oder mache ich alles falsch?

PS. Ich habe darüber nachgedacht, das Attribut InternalsVisiableTo zu verwenden, aber ich habe das Gefühl, dass das ein bisschen riecht.

+0

Wenn es ein Open Source SDK ist, frage ich mich, warum Sie versuchen, die Verwendung Ihres Codes zu verhindern? Ich verstehe, wenn Sie versuchen, sicherzustellen, dass uns SDK "Benutzer" Objekte nicht instanziiert, aber für mich, das ist noch mehr ein Geruch (SRP, LSP). Kannst du mehr von deinen Einschränkungen erklären? –

Antwort

3

Schnellansicht wählen: es doesn‘ Es scheint so, als ob du etwas so Unterschiedliches tust, dass es etwas grundlegend falsches an Ninject gibt, dass du es modifizieren oder ersetzen musst. In vielen Fällen können Sie nicht direkt auf [die] Interna zugreifen, da sie auf einer unaufgelösten Abhängigkeitsinjektion beruhen. daher die Verwendung von Ninject an erster Stelle. Es klingt auch so, als ob Sie bereits eine interne Menge von Schnittstellen haben, weshalb die Frage gestellt wurde.

Gedanken: ein Problem mit Ninject direkt in Ihrem SDK oder Bibliothek ist, dass dann Ihre Benutzer Ninject in ihrem Code verwenden müssen. Dies ist wahrscheinlich kein Problem für Sie, weil es Ihre IoC-Wahl ist, also würden Sie es sowieso verwenden. Was, wenn sie einen anderen IoC-Container verwenden wollen, dann haben sie jetzt effektiv zwei laufende Duplizierungsanstrengungen. Schlimmer noch, wenn sie Ninject v2 benutzen wollen und Sie v1.5 benutzt haben, dann kompliziert das wirklich die Situation.

Bester Fall: wenn Sie Ihre Klassen Refactoring können, so dass sie alles, was sie über Dependency Injection brauchen bekommen dann ist dies die sauberste ist, weil die Bibliothek Code nicht braucht jeder IoC-Container. Die App kann die Abhängigkeiten verdrahten und es fließt einfach. Dies ist jedoch nicht immer möglich, da die Bibliotheksklassen manchmal Instanzen erstellen müssen, die Abhängigkeiten aufweisen, die nicht durch die Injektion aufgelöst werden können.

Vorschlag: Die CommonServiceLocator (und the Ninject adapter dafür) wurde für diese Situation (Bibliotheken mit Abhängigkeiten) entwickelt. Sie codieren für den CommonServiceLocator und dann gibt die Anwendung an, welcher DI/IoC tatsächlich die Schnittstelle sichert.

Es ist ein wenig schmerzhaft, dass Sie nun Ninject und CommonServiceLocator in Ihrer App haben müssen, aber der CommonServiceLocator ist ziemlich leicht. Ihr SDK/Bibliothekscode nur verwendet den CommonServiceLocator, der ziemlich sauber ist.

0

Ich denke, Sie brauchen nicht einmal das. IoC ist für öffentliche Dinge. Gehe direkt zu Interna.

Aber - das ist nur meine Intuition ...

0

erstellen sekundäre interne API, die von der externen API unterscheidet. Sie müssen möglicherweise die Spaltung manuell tun ...

-1

Sie können

  • Ninject ändern
  • einen anderen Container in den anderen Antworten
0

Ich werde für die InternalsVisibleTo-Lösung abstimmen. Eigentlich kein Geruch, wirklich. Der Sinn des Attributs ist es, die Art von Verhalten zu ermöglichen, das Sie wollen. Anstatt also durch alle möglichen komplizierten Ringe zu springen, damit die Dinge ohne es funktionieren, verwenden Sie einfach die Funktionalität des Frameworks, um dieses spezielle Problem zu lösen.

Ich würde auch vorschlagen, wenn Sie Ihre Wahl des Behälters aus dem Benutzer verbergen wollen, ILMerge mit dem Ninject Baugruppen mit Ihrem SDK Baugruppe zu kombinieren, und wenden Sie die /internalisierte Argument, um die Sichtbarkeit der Ninject Baugruppen ändern zu intern, so dass die Ninject Namespaces nicht aus Ihrer Bibliothek auslaufen (Entschuldigung, ich konnte keinen Link zu den ILMerge Dokumenten online finden, aber es gibt eine doc Datei im Download). Es gibt auch diese nice blog post über die Integration von ILMerge in Ihren Build-Prozess.

Verwandte Themen