私の記事では、間違った例、私の意見では、依存性注入の原則の使用を検討し、他のチーム開発者(またはおそらく他の誰かが行うかもしれません)がより良いコードを書くための動機を見つけようとします文盲の方法で、リファクタリングを行います。
だから、問題の本質。 プロジェクトでは、OData WebApiを使用し、すべてのコントローラーはベースから継承し、ベースクラスのGetServiceメソッドを使用します。これは、ApiControllerScopeContextMediator静的クラスを介して依存関係をプルします。
public abstract class ODataControllerBase : ODataController { protected T GetService<T>() { return ApiControllerScopeContextMediator.GetService<T>(this); } } internal static class ApiControllerScopeContextMediator { internal static T GetService<T>(ApiController controller) { return (T) controller.Configuration.DependencyResolver.GetService(typeof (T)); } }
Global.asaxでは、StructureMapを介してODataの依存関係プルを構成します。
GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver(container);
すべてのアクションで、コントローラーは、たとえば次のように、あらゆる場所でGetServiceメソッドを使用します。
public class DisconnectedAppsController : ODataControllerBase { public IHttpActionResult Get() { var query = GetService<IQuery<IQueryable<DisconnectedAppDomain>, DisconnectedAppFilter>>(); } }
しかし、なぜですか? 結局、コンストラクターインジェクションを使用することができます。
public DisconnectedAppsController(IQuery<IQueryable<DisconnectedAppDomain>, DisconnectedAppFilter> query){ _query = query; }
それで、「タヒチ、タヒチ」(コンストラクターインジェクション)または「彼らはここで私たちによく食べさせます」(GetService)?
私が見るこのコードの問題:
- コントローラーを単体テストでカバーすることはできません(IoCコンテナーを初期化しないと)
- KISSの原則によれば、追加の複雑さは必要ありませんが、YAGNIによると、System.Web.Http.Configuration.DependencyResolverに追加の結び付きがあります。ベータ版ではすでに構成を失いました
- クラスを見ると、クラスのすべての依存関係が明確に表示されていません
- DependencyResolverのGetServiceの使用は、本質的にアンチパターンであるService LocatorでIoC実装を使用しています
- Service Locator は SOLID 原則に違反しています
- OOP カプセル化の基本原則に違反しています
私が聞いた反対意見は何ですか:
- 理想的には、コントローラーはテストでカバーするにはあまりにも愚かなものである必要があり、それを必要とすることはありません。統合テストでカバーする場合
- Googleのリンクに基づいて現在の実装を拒否するのは理想的すぎるため、メリットはありません
- 開発者が書くコードを少なくすると便利です
- この方法で使用されるコードを多くの場所で変更すると、プロジェクトにエントロピーが導入されます。
- 別の面でのYAGNIメソッド-毎分明らかな利点がない場合、なぜ何かを変更する必要があるのか
- コントローラーでのコンストラクターの注入は不便です
数年前、Mark Simanの
本Dependency Injectionを読みました。 私は座って考えますが、DIと私はどうですか?利便性の愛または結婚?
使用材料:
マーク・シーマン「依存性注入」マーク・シーマンのブログMicrosoft MVC6 githubオープンソースプロジェクトSOLID wikiページYAGNI wikiページKISS wikiページ