1

Entity Framework 5 Code First、WebApi、ASPNET MVC 4、リポジトリと作業単位のパターンなどを使用してプロジェクトを作成しました。

私のアーキテクチャは次のとおりです。

  • POCOSの1つのプロジェクト
  • コンテキスト、リポジトリ、作業単位などを含む1つのプロジェクト
  • 契約のある1つのプロジェクト(IRepository、IUnitOfWorkなど)
  • モデルのエンティティ(GET、POST、PUT、DELETE)ごとにApiControllerを保持する1つのWebApiプロジェクト。

さて、SPAを使いたくなくて(今は学ぶ時間がないので)、すぐに何かをしたいのなら、どうすればいいですか?コントローラーがApiControllerではなくControllerを継承し、それらのコントローラーがWebApiコントローラーを使用する新しいASPNET MVC 4プロジェクト?

このような?

public ActionResult Index()
{
    return View(WebApiProj.Uow.Houses.GetAll());
}

他のプロジェクトでWebApiコントローラーを指すGetを作成する必要があるため、これはあまり良くないようです。

私はこのアーキテクチャについて考えています。モバイルクライアント、Webクライアント、およびその他のクライアントが同じサービスを呼び出すため、これは良さそうです。

このアーキテクチャに関するアドバイスはありますか?長所または短所?

4

2 に答える 2

2

あなたが見せていることが可能かどうかわかりませんか?WebApiProj.Uow.Houses.GetAll()は、HousesをstaticGetAll関数が設定されたクラスであるかのように処理しています。Housesは、リクエストごとにインスタンス化する必要があるインスタンスクラスであり、コンストラクタインジェクションの問題も処理する必要がある場合があります... GetAllは通常、インスタンスメソッドです。

複数のコードクライアント、つまりWebApiコントローラーとMVCコントローラーを使用する状況では、プロジェクトにサービスレイヤーを追加することを検討する必要があります。http://martinfowler.com/eaaCatalog/serviceLayer.html

サービスレイヤーはおそらく単一のクラスの形式を取ります(これが小さなishプロジェクトであるが、必要に応じて分割する場合)、リポジトリとインフラストラクチャコードが挿入されます。最終的には、リポジトリ、ファクトリ、および作業クラスのユニット間のオーケストレーションロジックを含む一連のCRUDおよびUseCaseサウンディングメソッド名になります。

public interface IMyServiceLayerClass
{
      IEnumerable<House> GetAllHouses();
      House SaveHouse(House house);
      IEnumerable<Windows> GetAllHouseWindows(int houseId);
      //etc
}

public class MyServiceLayerClass : IMyServiceLayerClass
{
     private readonly IRepository<House>  _houseRepository;
     private readonly IUnitOfWork  _unitOfWork;
     private readonly IRepositoryTypeB _repositoryTypeB; 

     Public MyServiceLayerClass(IUnitOfWork unitofwork, IRepository<House> houseRepository, IRepositoryTypeB repositoryTypeB)
     {
           //Populate the private readonly's
     }

     public IEnumerable<House> GetAllHouses()
     {
         return _houseRepository.GetAll();
     }

2つのタイプのコントローラーは、Serviceクラスを受け入れ、サービスレイヤーに転送するためだけに非常に薄いロジックを持つことができます。

public class HomeController : Controller
{
    private readonly IMyServiceLayerClass _myServiceLayerClass;

    public HomeController(IMyServiceLayerClass myServiceLayerClass)
    {
        _myServiceLayerClass= myServiceLayerClass;
    }

    public ViewResult Index()
    {
         return View(_myServiceLayerClass.GetAllHouses());
    }

Apiについても同じです。

public class HouseController : ApiController
{
    private readonly IMyServiceLayerClass _myServiceLayerClass;

    public HouseController (IMyServiceLayerClass myServiceLayerClass)
    {
        _myServiceLayerClass= myServiceLayerClass;
    }

    public IEnumerable<House> Get()
    {
         return _myServiceLayerClass.GetAllHouses();
    }

これにより、同じビジネスロジックを再利用でき、コントローラー間でオーケストレーションを使用して、WebApiおよびMvcアプリケーションからロジックを抽象化できます。

このコードは、インターフェースにのみ依存しているため、コントラクトを定義するプロジェクトに簡単に組み込むことができます。または、そのインターフェイスをコントラクトに追加してから、サービスクラスの実装を保持できる別のプロジェクトクラスドメインまたはサービスを作成することもできます。

コントローラーに最善を尽くしてもらい、UI固有の要素の委任を処理させ、UI固有ではないロジックを再利用可能なサービスレイヤーにリファクタリングさせることを強くお勧めします。これにより、コントローラーの単体テストで正しいアクション結果やステータスコードなどのテストに集中できるようになり、ドメインロジックを個別にテストできるようになります。

于 2012-11-19T10:09:37.523 に答える
1

MVCに関する別のアーキテクチャの質問に対する私の答えを見てください。質問の鍵は、MVCコントローラーとWeb APIコントローラーの両方がビジネスモデル(MVCのM)にアクセスするために使用できるアプリケーションまたはドメインレイヤーを用意することです。ここでは不要なシリアル化と逆シリアル化のオーバーヘッドがあるため、MVCコントローラーから直接WebAPIを呼び出す必要はありません。代わりに、アプリケーション/ドメインレイヤーを直接呼び出します。

于 2012-11-19T14:25:52.683 に答える