あなたは私が数年前の状態にいるようですね。
さらにサポートが必要な場合は、コードをお送りします。ここにすべてのコードを入れるのは難しいです。
私が取り組んでいるプロジェクトの現在のアーキテクチャについて説明しようと思います。この投稿は少し長めですが、IOCの使用が多くの点でどのように役立つかについて全体像を示したいと思います。
だから私はNinjectを使います。Castle Windsorをしばらく使用しようとした後、Ninjectは簡単に起動して実行できることがわかりました。Ninjectには、始めるのに役立つクールなWebサイトがあります。
まず、私のプロジェクト構造は次のとおりです:(トップダウンでMVCです)
ビュー-かみそり
ViewModel-ビューごとに1つのビューモデルを使用します
ViewModelBuilder-ビューのビューモデルを構築します(コントローラーからコードを抽象化して、コントローラーを整理整頓するために使用します)
AutoMapper-ドメインエンティティをビューモデルにマップします
コントローラ-サービスレイヤーを呼び出してドメインエンティティを取得します
ドメインエンティティ-私のドメインの表現
ServiceLayer(ビジネスレイヤー) -リポジトリレイヤーを呼び出して、ドメインエンティティまたはこれらのコレクションを取得します
AutoMapperをもう一度-サードパーティベンダーのカスタムタイプをドメインエンティティにマッピングします
RepositoryLayer-データストアに対してCRUD操作を行います
これは階層ですが、ドメインエンティティは一種の横に並んでおり、いくつかの異なるレイヤーで使用されます。
注:この投稿で言及されているいくつかの追加ツールは次のとおりです。
AutoMapper-エンティティを他のエンティティにマップします-大量のマッピングコードを記述する必要がなくなります
Moq-ユニットテスト用のモックを作成できます。これについては後で説明します。
さて、Ninjectについて。
各レイヤーはインターフェースでマークされています。これは、Ninjectが自分自身に言うことができるようにする必要があります。
IVehicleRepositoryを見つけたら、実際のVehicleRepositoryを注入するか、偽物が必要な場合はFakeVehicleRepositoryを注入します。
(これはあなたのコメントに関連しています-「これにより、すべてをテストXMLリポジトリにバインドできるようになります」)
これで、すべてのレイヤーにコンストラクターが追加され、Ninject(またはその他のIOCコンテナー)が必要なものを注入できるようになりました。
public VehicleManager(IVehicleRepository vehicleRepository)
{
this._vehicleRepository = vehicleRepository;
}
VehicleManagerは私のserviceLayerにあります(Webサービスに関係するものと混同しないでください)。サービスレイヤーは、実際にはビジネスレイヤーと呼ばれるものです。多くの人がワードサービスを利用しているようです。(ビジネスレイヤーだけでなく、WebサービスやWCFについて考えるのは面倒だと思いますが、とにかく...)
Ninjectセットアップの要点に立ち入ることなく、NinjectWebCommon.csの次のコード行がninjectに何をすべきかを指示します。
kernel.Bind<IVehicleRepository>().To<VehicleRepository>().InRequestScope();
これは言う:
ねえNinject、IVehicleRepositoryを要求するとき、VehicleRepositoryの具体的な実装を教えてください。
前に述べたように、VehicleRepositoryをFakeVehicleRepositoryに置き換えて、実際のデータベースから読み取る必要がないようにすることができました。
したがって、今想像できるように、すべてのレイヤーはインターフェースにのみ依存しています。
どれだけの単体テストを実行したかはわかりませんが、サービスレイヤーを単体テストする必要があり、リポジトリレイヤーへの具体的な参照がある場合は、実際に単体テストを実行するため、単体テストを実行できないことも想像できます。リポジトリ、したがって実際のデータベースからの読み取り。
ユニットテストは、1つのことだけをテストするため、ユニットテストと呼ばれることを忘れないでください。したがって、UNITという単語。つまり、すべてがインターフェースについてしか知らないため、サービスレイヤーでメソッドをテストし、リポジトリをモックできることを意味します。
したがって、サービスレイヤーに次のようなメソッドがある場合:
public bool ThisIsACar(int id)
{
bool isCar = false;
var vehicle = vehicleRepository.GetVehicleById(id);
if(vehicle.Type == VehicleType.Car)
{
isCar = true;
}
else
{
isCar = false;
}
}
VehicleRepositoryが呼び出されることを望まないので、VehicleRepositoryが返すものをMoqできます。ほとんどの場合、インターフェースを実装している場合にのみモックを作成できます。
So your unit test would look like this (some pseudo code here):
[TestMethod]
public void ServiceMethodThisIsACar_Returns_True_When_VehicleIsACar()
{
// Arrange
_mockRepository.Setup(x => x.ThisIsACar(It.IsAny<int>)).returns(new Car with a type of VehicleType.Car)
// Act
var vehicleManager = new VehicleManager(_mockVehicleRepository.Object);
var vehicle = vehicleManager.ThisIsACar(3);
// Assert
Assert.IsTrue(vehicle.VehicleType == VehicleType.Car)
}
ご覧のとおり、この時点では非常に単純化されているため、サービスレイヤーでIFステートメントをテストして、結果が正しいことを確認するだけです。
リポジトリを独自の単体テストでテストし、使用している場合はエンティティフレームの動作をモックする可能性があります。
したがって、全体として、IOCコンテナーを使用すると、最小限の苦痛で最速で稼働できるようになります。
また、できる限りのユニットテストを試してみてください。これは、いくつかの異なる理由で素晴らしいです。明らかに、あなたが書いたコードをテストしますが、具体的なリポジトリを新しくするなどの愚かなことをしたかどうかもすぐに表示されます。単体テストをモックするためのインターフェースがないことがすぐにわかります。これにより、戻ってコードをリファクタリングすることができます。
IOCを使用すると、取得するのに時間がかかることがわかりました。ある日カチッと音がするまで、それはあなたのがらくたを混乱させます。その後、それなしでどのように生きたのか不思議に思うのはとても簡単です。
Automapper Moq Fluent Validation Resharperなしでは生きていけないもののリストを次に示します。嫌いな人もいますが、主にユニットテストUIのために気に入っています。
とにかく、これは長くなりすぎています。どう考えているか教えてください。
ありがとうRuSs