将对象注入为延迟加载

Inject object as lazy loading

我有如下所示的 MVC 代码。我使用 nInject 作为 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);
    }
}

嗯,不确定 ninject 特别是,但通常不会,您会在控制器实例化时获得对象的实例。

备选方案是:

做两个控制器(我推荐这个)

注入工厂而不是对象

个人认为这不适合我,我认为 IoC 容器应该是你的工厂。

public ActionResult SendMail(string mailAddress)
    {
        _mailSrvFactory.Create().Do(mailAddress);
    }

在方法中直接绑定对象而不是注入

这通常被认为是 'bad' 因为你必须传递 IoC 容器

public ActionResult SendMail(string mailAddress)
    {
        kernel.Get<IMailServer>().Do(mailAddress);
    }

我想从更深的层次来看,也许可以创建一个自定义范围,它实际上将 class 包装在工厂中,就像 IoC 容器可以提供的方式一样 classes 作为单身人士。不过我得考虑一下

刚刚试了一下。

添加Ninject.Extensions.Factory to your project and change the member variables to 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);            
    }
}

现在将延迟创建实例。