2012-01-10 9 views
4

私たちはMVC3アプリケーションで、編集(作成/編集)、削除、リスト(私は既にhereのように見えました)を処理できる汎用CRUDコントローラを作成しようとしています。このプロジェクトには、Web(MVC)レイヤ、Service(BLL)レイヤ、およびRepository(DB)レイヤがあります。MVC3一般的なCRUDコントローラ、サービス、リポジトリ

SERVICE LAYER 
public class MyService : IMyService 
{ 
    private IMyRepository _myRepository; 

    public MySerivce(IMyRepository myRepository) 
    { 
     this._myRepository = myRepository; 
    } 

    public IEnumerable<IMyObject> GetObjects(int intParentKey) 
    { 
     return (IMyObject)_myRepository.GetObjects(intParentKey).Select(o => new MyObject(o));; 
    } 
} 


CONTROLLER 
public class MyController 
{ 
    private IMyService _myService; 

    public MyController(IMyService myService) 
    { 
     this._myService = myService; 
    } 

    public ActionResult Index() 
    { 
     return View("Index", new List<MyFormModel>(_myService.GetObjects(intKeyValue).Select(a => new MyFormModel(a)))); 
    } 
} 

目標は、一般的なCRUDコントローラを持っていることですが、難易度は、コントローラがMyFormModelオブジェクトの知識だけでなく、特定のサービスを持っている必要がありますということです。次のように私たちは、コンストラクタ依存性注入を使用しています。また、GetObjects、SaveObject、DeleteObject関数を処理する汎用サービスを用意したいと思いますが、IMyObjectインターフェイス、IMyObjectのMyObject実装、IMyRepositoryタイプの知識が必要です。これは、依存性注入を使用してこれをすべて行うことはやや複雑です。

FYIでは、サービスレイヤーは、現在の設定に応じて、ツールのWEB部分でオンザフライで変更する必要があります。一般的なCRUDのコメントを受けて

は、ここでの依存性注入を介してベースサービスを受け入れるBASEコントローラです:

public abstract class BaseCRUDController<T> 
    where T : class 
{ 
    private IBaseService _baseService; 

    public BaseCRUDController(IBaseService baseService) 
    { 
     this._baseService = baseService; 
    } 

    public ActionResult Index() 
    { 
     Type classType = typeof(T); 
     ConstructorInfo ciClass = classType.GetConstructor(new Type[] {}); 
     return View("Index", new List<T>(_baseService.GetObjects(intKey).Select(o => (T)ciClass.Invoke(new object[] { o })))); 
    } 
} 

明らかに、この汎用コントローラーはかなり簡単ですが、難易度は、サービスから来ていますIMyObjectオブジェクトとMyObjectオブジェクトが存在する場所です。一般的なBaseServiceの定義では、回避しようとしているすべてのオブジェクトのタイプをベースコントローラーに含める必要があります。以下のコードは、遠く離れて、私は助けを求めています理由ですマークのようになります。

SERVICE CLASS 
public class MySerivce : BaseService<IMyObject, MyObject, DBObject> 
{ 
    public MySerivce(IMyRepository myRepository) : 
     base(myRepository) 
    { 
    } 
} 

BASE SERVICE INTERFACE 
public interface IBaseService<IMT, MT, DT> 
    where IMT : class 
    where MT : class 
    where DT : class 
{ 
    IEnumerable<ValidationResult> Save(IMT model); 
    void Delete(int intKey); 
    IMT Get(int? intKey); 
    IEnumerable<IMT> GetObjects(int intParentKey); 
} 


BASE SERVICE IMPLEMENTATION 
public class BaseService<IMT, MT, DT> : IBaseService<IMT, MT, DT> 
where IMT : class 
where MT : class 
where DT : class 
{ 
private IBaseRepository _baseRepository; 

public BaseService(IBaseRepository baseRepository) 
{ 
    this._baseRepository = baseRepository; 
} 

public IEnumerable<ValidationResult> Save(IMT model) 
{ 
    List<ValidationResult> lResults = new List<ValidationResult>(); 

    if (Validator.TryValidateObject(model, new ValidationContext(model, serviceProvider: null, items: null), lResults)) 
    { 
     Type tDT = typeof(DT); 
     ConstructorInfo ciDTClass = tDT.GetConstructor(new Type[] { }); 
     DT dtObject = (DT)ciDTClass.Invoke(new object[] { }); 
     Mapper.CreateMap<IMT, DT>(); 
     Mapper.Map(model, dtObject); 

     _baseRepository.Save<DT>(dtObject); 
    } 

    return lResults; 
} 

public void Delete(int intKey) 
{ 
    _baseRepository.Delete<DT>(intKey); 
} 

public IMT Get(int? intKey) 
{ 
    Type tMT = typeof(MT); 
    ConstructorInfo ciMTClass = tMT.GetConstructor(new Type[] { }); 
    DT dtObject = _baseRepository.Get<DT>(intKey); 

    if (dtObject == null) 
    { 
     Type tDT = typeof(DT); 
     ConstructorInfo ciDTClass = tDT.GetConstructor(new Type[] { }); 
     dtObject = (DT)ciDTClass.Invoke(new object[] { }); 
    } 

    return (IMT)ciMTClass.Invoke(new object[] { dtObject }); 
} 

public IEnumerable<IMT> GetObjects(int intParentKey) 
{ 
    Type tMT = typeof(MT); 
    ConstructorInfo ciMTClass = tMT.GetConstructor(new Type[] { }); 
    IEnumerable<DT> dbObjects = _baseRepository.GetObjects<DT>(intParentKey); 

    return (IEnumerable<IMT>)dbObjects.Select(o => (MT)ciMTClass.Invoke(new object[] { o })); ; 
} 
} 
+0

あなたは_generic CRUDのcontroller_で何を意味するのですか?異なるタイプのオブジェクト(_MyObject_、_MyObject2_など)を扱う_IMyService_(これは非ジェネリックインターフェイス)の実装を入れたいのですが、異なるサービスが扱うオブジェクトをコントローラに伝えたくないのですか? –

+0

ジェネリックは間違った用語だと思います。編集/削除/リストアクションを処理するBASEコントローラが必要です。私はより良い説明のために別のコードセットを掲載します。 – wigs

答えて

-2

MVCがすでに使用している場合、実際に、それは、あなたのためのコードの95%を生成します、一般的なCRUD機能を提供しますビルトインツーリングおよび/またはスキャフォールディング機能

基本的なチュートリアルを確認すると、これを行う方法がわかります。例えば

http://blog.stevensanderson.com/2011/01/13/scaffold-your-aspnet-mvc-3-project-with-the-mvcscaffolding-package/

+3

それでも、本質的に重複しているコード(タイプを除いたもの)を作成していませんか?自動化されたプロセスがあなたのためにやったことは? – wigs

+0

タイプとタイプ処理はコードの95%です。すべてがそのタイプに固有のものです。確かに、混乱したリフレクションベースのシステムを1セットのコードで実行することはできますが、ツールを使用してコードを生成するのに要する時間は、5秒間を維持して100倍以上かかることはありません。それはそれだけの価値はありません。 –

関連する問題