MVC3通用CRUD控制器,服务和存储库

时间:2012-01-10 20:54:14

标签: asp.net-mvc-3 dependency-injection controller crud

我们正在尝试在我们的MVC3应用程序中创建一个通用的CRUD控制器,它可以处理以下操作:编辑(创建/编辑),删除和列表(我已经看过here)。该项目具有Web(MVC)层,服务(BLL)层和存储库(DB)层。我们使用构造函数依赖注入如下:

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注释,这里是一个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 }))));
    }
}

显然这个通用控制器相当简单,但困难来自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 个答案:

没有答案