C# 作为延迟加载注入对象

C# 作为延迟加载注入对象,c#,.net,model-view-controller,ninject,inversion-of-control,C#,.net,Model View Controller,Ninject,Inversion Of Control,我有如下的MVC代码。我用nInject来代表国际奥委会。 我想知道当我推送请求时,例如SendMail有一个create controller对象,nInject为两个只读对象创建子对象:\u mailSrv和\u dbSrv,但我在这个请求中只需要一个变量。 是否可以将变量作为延迟加载注入。当代码需要对象时,会创建它吗 public class HomeController:Controller { private readonly IMailService _mailSrv;

我有如下的MVC代码。我用nInject来代表国际奥委会。 我想知道当我推送请求时,例如SendMail有一个create controller对象,nInject为两个只读对象创建子对象:\u mailSrv\u 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);
    }
直接绑定方法中的对象,而不是注入

这通常被认为是“不好的”,因为您必须传递IoC容器

public ActionResult SendMail(string mailAddress)
    {
        kernel.Get<IMailServer>().Do(mailAddress);
    }
public ActionResult SendMail(字符串mailAddress)
{
kernel.Get().Do(mailAddress);
}
我想从更深的层次来看,可能会创建一个自定义作用域,该作用域实际上将类包装在工厂中,就像IoC容器可以将类作为单例提供一样。我得考虑一下,不过我刚刚试过了

添加到项目中,并将成员变量更改为

公共类HomeController:控制器
{
私有只读的Lazy_mailSrv;
私有只读惰性_dbSrv;
公共HomeController(惰性邮件SRV、惰性dbSrv)
{
_mailSrv=mailSrv;
_dbSrv=dbSrv;
}
公共操作结果SendMail(字符串mailAddress)
{
_mailSrv.Value.Do(邮件地址);
}
public ActionResult SaveToDatabase(整数id,字符串数据)
{
_dbSrv.Value.Do(id,数据);
}
}
现在将延迟创建实例

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);            
    }
}