2012-01-10 25 views
4

我們正試圖在我們的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 })); ; 
} 
} 
+0

你是什麼意思與_Generic CRUD controller_?你想放入不同類型的對象(_MyObject_,_MyObject2_等)的_IMyService_(這是一個非泛型接口)的不同實現,但你不想告訴你的控制器不同的服務處理什麼對象? – 2012-01-10 21:15:37

+0

我猜泛型是錯誤的術語。我想要一個BASE控制器來處理編輯/刪除/列表操作。我會發布另一組代碼以獲得更好的解釋。 – wigs 2012-01-10 21:37:55

回答

-2

MVC已經提供了通用的CRUD功能,實際上,它會生成代碼的95%給你,如果你使用的內置工具和/或腳手架功能。

檢查基本教程,它會告訴你如何做到這一點。例如

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

+3

這不是仍然創造什麼本質上重複的代碼(減去類型)?它只是一個自動化的過程爲你做的嗎? – wigs 2012-01-10 21:56:45

+0

類型和類型處理是95%的代碼。所有類型都是獨一無二的。當然,你可以編寫一個混亂的基於反射的系統,在一組代碼中完成所有這些工作,但維護起來很困難,並且花費比使用工具爲您生成代碼所需的5秒鐘多100倍的時間。這不值得。 – 2012-01-10 22:01:34