2012-01-10 3 views
4

우리는 MVC3 응용 프로그램에서 편집 (만들기/편집), 삭제 및 목록 (이미 here)을 처리 할 수있는 일반 CRUD 컨트롤러를 만들려고합니다. 이 프로젝트에는 웹 (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 유형에 대한 지식이 필요합니다. 의존성 주입으로이 모든 작업을 수행하는 것은 다소 복잡합니다.

참고로, 서비스 계층은 현재 구성에 따라 도구의 웹 부분에서 즉시 변경해야합니다.

일반적인 CRUD 주석에 대한 응답으로

, 여기에 의존성 주입을 통해 BASE 서비스를 받아들이는 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 })))); 
    } 
} 

은 분명히이 일반적인 컨트롤러는 매우 간단하지만 어려움은 서비스에서 제공 side는 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

제네릭이 잘못된 용어라고 생각합니다. 편집/삭제/목록 작업을 처리 할 기본 컨트롤러가 필요합니다. 나는 더 나은 설명을 위해 또 다른 코드를 게시 할 것이다. – wigs

답변

-2

MVC는 이미 당신이 사용하는 경우 일반적인 CRUD 기능은, 사실, 그것은 당신을 위해 코드의 95 %를 생성합니다 제공 내장형 공구 및/또는 스캐 폴딩 기능.

기본 자습서를 확인하면이를 수행하는 방법을 알려줍니다. 예를 들어

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

+3

본질적으로 중복 코드 (유형 제외)는 여전히 생성되지 않습니까? 자동 프로세스가 당신을 위해 해낸 것입니까? – wigs

+0

유형 및 유형 처리는 코드의 95 %입니다. 모든 유형에 고유합니다. 물론, 혼잡 한 반사 기반 시스템을 작성하여 단일 코드 세트로 처리 할 수는 있지만 도구를 사용하여 코드를 생성하는 데 소요되는 5 초보다 100 배 더 많은 시간을 유지 관리하는 것은 어려울 것입니다. 그것은 가치가 없어. –