我們正試圖在我們的MVC3應用程序中創建一個通用的CRUD控制器,它可以處理以下操作編輯(創建/編輯),刪除和列表(我已經查看here)。該項目具有Web(MVC)層,服務(BLL)層和存儲庫(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類型的知識。現在看來,用依賴注入做這些事情有點複雜。根據當前配置,服務層需要在工具的WEB部分中隨時更改。
針對通用CRUD評論,這裏是一個基本的控制器,其通過依賴注入接受基本服務:
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_(這是一個非泛型接口)的不同實現,但你不想告訴你的控制器不同的服務處理什麼對象? – 2012-01-10 21:15:37
我猜泛型是錯誤的術語。我想要一個BASE控制器來處理編輯/刪除/列表操作。我會發布另一組代碼以獲得更好的解釋。 – wigs 2012-01-10 21:37:55