我有如下的MVC代码。我使用nInject for IoC。
我想知道当我推送请求时,例如 SendMail 有创建控制器对象,nInject为两个只读对象创建子对象: _mailSrv 和 _dbSrv ,但我在此请求中只需要一个变量。
是否可以将变量注入延迟加载。当代码需要对象时,它会被创建吗?
public class HomeController:Controller
{
private readonly IMailService _mailSrv;
private readonly IDatabaseService _dbSrv;
public HomeController:Controller(IMailService mailSrv, IDatabaseService dbSrv)
{
_mailSrv = mailSrv;
_dbSrv = dbSrv;
}
public ActionResult SendMail(string mailAddress)
{
_mailSrv.Do(mailAddress);
}
public ActionResult SaveToDatabase(int id, string data)
{
_dbSrv.Do(id, data);
}
}
答案 0 :(得分:5)
试了一下。
将Ninject.Extensions.Factory添加到项目中,并将成员变量更改为Lazy。
public class HomeController : Controller
{
private readonly Lazy<IMailService> _mailSrv;
private readonly Lazy<IDatabaseService> _dbSrv;
public HomeController(Lazy<IMailService> mailSrv, Lazy<IDatabaseService> dbSrv)
{
_mailSrv = mailSrv;
_dbSrv = dbSrv;
}
public ActionResult SendMail(string mailAddress)
{
_mailSrv.Value.Do(mailAddress);
}
public ActionResult SaveToDatabase(int id, string data)
{
_dbSrv.Value.Do(id, data);
}
}
现在将懒惰地创建实例。
答案 1 :(得分:2)
嗯,特别是对ninject不确定,但通常不会,在实例化控制器时会得到对象的实例。
替代方案是:
制作两个控制器(我建议这个)
注入工厂而不是对象
就我个人而言,我认为IoC容器应该是您的工厂。
public ActionResult SendMail(string mailAddress)
{
_mailSrvFactory.Create().Do(mailAddress);
}
直接绑定方法中的对象而不是注入
这通常被视为“不好”。因为你必须传递IoC容器
public ActionResult SendMail(string mailAddress)
{
kernel.Get<IMailServer>().Do(mailAddress);
}
我想在更深层次上看一下,有可能创建一个自定义范围,它实际上将类包装在工厂中的方式与IoC容器可以提供类作为单例的方式相同。我不得不考虑那个