从基本控制器派生控制器的正确方法

时间:2010-12-28 13:44:55

标签: asp.net-mvc

我倾向于从我的所有控制器中使用相同的存储库集。也就是说,我在每个控制器中实例化存储库对象(使用IoC)。

我想我可以从一个可以在一个地方实例化这些对象的基本控制器派生我的控制器。你能指出我这样做的权利吗?谢谢你的帮助。

2 个答案:

答案 0 :(得分:3)

您有多种选择,哪一种是“正确的方式”取决于您以及您的系统如何整体运作。可能存在需要考虑的各种实例化对象的性能问题等。

一个选项可能很简单:

public class BaseController
{
    protected ISomeRepository myRepository = IoCContainer.Resolve<ISomeRepository>();
}
public class MyController : BaseController { }

此外,您可以将初始化移动到基本控制器的构造函数,而不是像它那样内联。

另一种选择可能是对存储库进行后期绑定,如果它们都会导致性能损失(仔细权衡实例化它们),并且平均而言并不总是需要它们:

public class BaseController
{
    private ISomeRepository _myRepository;
    protected ISomeRepository myRepository
    {
        get
        {
            if (_myRepository == null)
                _myRepository = IoCContainer.Resolve<ISomeRepository>();
            return _myRepository;
        }
    }
}

您可能有更多选择,这一切都取决于您的设置。您的特定IoC容器如何工作也可能会对您的设计决策产生重大影响。

(请注意,为了简洁起见,我在这里直接引用了IoCContainer,但我建议在服务定位器后面抽象出容器,这样就不会有太多对容器本身的引用。)

答案 1 :(得分:1)

实际上,这取决于那些“Common Repositories”应该完成的任务类型。如果他们与行动应该做的直接相关 - 也许这没关系。但是你无论如何都要面对IoC解决方案的一些问题。为了避免每次新Repo都注入这些存储库,您必须依赖基本控制器中的Service Locator。这不是好事。

如果这些存储库是与Action将要做的事情正交的东西 - 那么它更像是AOP-kinda逻辑,所以我最好使用Action Filters或RenderAction

在一般情况下,我会尝试避免使用图层超类型依赖项,并且希望合成而不是继承