通过控制器工厂注入实例

3

我正在学习依赖注入,需要帮助更好地理解控制器工厂。

enter image description here

我需要通过构造函数注入HomeController中注入SqlReceitaRepository

HomeController构造函数

private readonly IReceitaRepository repositorio;

public HomeController(IReceitaRepository repositorio)
{
    if (repositorio == null)
       throw new ArgumentException("repositorio");

    this.repositorio = repositorio;
}

有了实现了 SqlReceitaRepository 的代码,我现在可以设置 ASP.NET MVC 注入它的实例到 HomeController 的实例中,但是我应该如何做呢?

详细信息:我使用的是 NHibernate 而不是 Entity Framework。

如果需要,那么用于完成此任务的类将属于哪个层?

我阅读了一些文章,发现我需要在我的 Global.asax 中添加一行新的代码。

Global.asax

var controllerFactory = new ReceitaControllerFactory();
ControllerBuilder.Current.SetControllerFactory(controllerFactory);

我假设ReceitaControllerFactory应该包含IControllerFactory的实现。

但是查看IControllerFactory...

public interface IControllerFactory
{
    IController CreateController(RequestContext requestContext, string controllerName);
    SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName);
    void ReleaseController(IController controller);
}

我们可以看到CreateController方法,但是我该如何将SqlReceitaRepository的实例注入到HomeController的实例中呢?

我喜欢一个好的插图,干得好,点赞 :D - Smithy
1个回答

2
简单的回答是:
IController CreateController(RequestContext requestContext, string controllerName)
{
    return new HomeController(new SqlReceitaRepository());
}

但是,正如你可能已经注意到的那样,这只适用于一个控制器类型,而且它的可维护性不高。因此,正确的做法是获取一个流行的DI框架,例如Ninject,并获取您所需的框架插件(例如Ninject MVC),然后定义您的绑定,让框架处理依赖关系的解析:
Bind<IReceitaRepository>().To<SqlReceitaRepository>();

这比我想象的要简单得多,我正在学习依赖注入,并且想法是在开始时通过一些 DI 容器(如您所说的 Ninject、Unity、Castle Windsor 等)来“减轻负担”。感谢您的解释。 - Lucas_Santos
使用第一种方法(不依赖 DI 容器),由于 SqlReceitaRepository 类在数据访问层中,呈现层将需要依赖于数据访问层。 - Lucas_Santos
@Lucas_Santos:这有点取决于你的架构,但是没错,当你尝试自己编写DI帮助程序时,这些问题就会出现。你需要想办法处理来自所有层的对象构建,而不会将其他代码紧密耦合在不应该耦合的方式上。DI框架已经基本解决了这些问题。 - StriplingWarrior

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接