私たちは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 })); ;
}
}
あなたは_generic CRUDのcontroller_で何を意味するのですか?異なるタイプのオブジェクト(_MyObject_、_MyObject2_など)を扱う_IMyService_(これは非ジェネリックインターフェイス)の実装を入れたいのですが、異なるサービスが扱うオブジェクトをコントローラに伝えたくないのですか? –
ジェネリックは間違った用語だと思います。編集/削除/リストアクションを処理するBASEコントローラが必要です。私はより良い説明のために別のコードセットを掲載します。 – wigs