2014-03-04 12 views
5

Ich versuche, Dependency-Injektion in der gesamten App-Ebene zu tun und bin in ein Szenario laufen, die andere sicher gesehen haben. Es gibt einige Webdienste von Drittanbietern, die wir nutzen, und die Clients wurden automatisch mit einer Basisklasse generiert. Die Clients haben keine Schnittstelle und die Datentypen befinden sich in derselben Datei/demselben Projekt.DI mit automatisch generierten Web-Service-Clients

Das offensichtliche Problem ist, wenn ich Unit-Tests machen will, muss ich den Dienst verspotten. Ich muss eine Schnittstelle extrahieren und die Datentypen in ein "Vertrags" -Projekt verschieben, das für echte/falsche Clients verfügbar ist. Wenn der Client das nächste Mal automatisch generiert wird, muss diese Arbeit jedoch erneut ausgeführt werden. Das Erstellen eines Proxys zur Laufzeit würde nicht viel helfen, denn dann müssten wir die Schnittstellen und Datentypen manuell aus der WSDL erstellen. Gibt es einen besseren Weg, damit umzugehen?

+4

Würden Shims via Microsoft Fakes für Sie in diesem Szenario von Nutzen sein? http://msdn.microsoft.com/en-us/library/hh549175.aspx –

+0

@ BrendanGreen - +1 für etwas Neues, das ich heute gelernt habe. Dies könnte wahrscheinlich funktionieren, aber da ich die Kontrolle über den Client-Code habe, möchte ich diese Route möglichst vermeiden. Definitiv ein gutes Werkzeug für die Zukunft. –

Antwort

5

Das Extrahieren einer Schnittstelle von der Implementierung wird dir sowieso nicht viel helfen, da es eine schlechte Abstraktion sein wird.

Schnittstellen sollten von den Clients, die die Schnittstellen nutzen, definiert sein und ihnen gehören. Als Agile Principles, Patterns, and Practices erklären, "Clients [...] besitzen die abstrakten Schnittstellen" (Kapitel 11). Daher wird jeder Versuch, eine datenzentrische Schnittstelle wie das Extrahieren von Schnittstellen von automatisch generierten Web-Service-Clients zu definieren, früher oder später zu Problemen führen, da sie gegen verschiedene SOLID-Prinzipien wie das Dependency Inversion-Prinzip oder das Interface Separation Principle verstoßen.

Stattdessen sollte Ihr Client-Code die Schnittstellen definieren, die sie benötigen. Dann können Sie immer diese Schnittstellen mit den automatisch generierten Web-Service-Clients implementieren. Wenn Sie die Werkzeuge von Microsoft (Visual Studio, wsdl.exe usw.) verwendet haben, sollte die entsprechende automatisch generierte Klasse bereits eine Teilklasse sein, was bedeutet, dass Sie Verhalten hinzufügen können, ohne die automatisch generierte zu berühren ein Teil davon.

+0

Versucht zu verstehen ... warum würde das Extrahieren einer Schnittstelle das DI-Prinzip verletzen? Der Rest des Codes würde nur auf die Schnittstelle verweisen und die Instanz könnte von einem IoC-Container bereitgestellt werden. Schnittstellentrennung Ich verstehe, da das Extrahieren einer Schnittstelle wahrscheinlich zu unnötigen Mitgliedern führt, aber sie könnte als Startpunkt verwendet werden und sie bereinigen, wenn Sie wahrscheinlich die meisten/all das verwenden, was der Dienst bereitstellt. –

+0

In Bezug auf den Client, der die Schnittstelle und die partielle Klasse besitzt, sagst du, dass ich Geschäftslogik in einer partiellen Klasse hinzufügen sollte, um von der Schnittstelle zu dem zuzuordnen, was der Dienst tatsächlich bietet? Das ist ein interessantes Konzept, so dass der Code, der von der Schnittstelle abhängt, sich nicht notwendigerweise ändern muss, wenn sich der Service ändert, aber wenn er komplex genug wird, möchte ich diese Geschäftslogik testen und bin wieder da, wo ich angefangen habe. –

+0

Der DIP sagt, dass "Abstraktionen nicht von Details abhängen sollten. Details sollten von Abstraktionen abhängen." Wenn die Schnittstelle im selben Paket wie der Service definiert ist, hängt der Client vom Servicepaket ab (ein Implementierungsdetail). Aus diesem Grund gibt das DIP an, dass Kunden die benötigten Schnittstellen besitzen sollten. Und ja, Sie müssten wahrscheinlich die Konvertierungslogik testen, aber das ist keine Geschäftslogik, das ist Teil des Implementierungsdetails. Die Geschäftslogik sollte das unabhängige Paket (die unabhängigen Pakete) sein: http://blog.ploeh.dk/2013/12/03/layers-onions-ports-adapters-its-all-the-same –

Verwandte Themen