【问题标题】:MVC Postal Emailer Conflicting With Mvc.Unity4MVC Postal Emailer 与 Mvc.Unity4 冲突
【发布时间】:2015-02-05 19:15:08
【问题描述】:

我在尝试在同样使用 Mvc.Unity4 的 MVC 应用程序中使用 Postal 时遇到了一个奇怪的问题。

我认为问题是由于无法访问 HttpContext 而引发的。

我尝试使用 Postal 从我的一个控制器内部发送电子邮件:

dynamic e = new Email("AccountActivation");
e.To = "name@email.com"
e.Send();

尝试发送电子邮件会导致Unity.Mvc4.UnityDependencyResolver 内出现以下异常:

[NullReferenceException: Object reference not set to an instance of an object.]
   Unity.Mvc4.UnityDependencyResolver.get_ChildContainer() +57
   Unity.Mvc4.UnityDependencyResolver.GetService(Type serviceType) +241
   System.Web.Mvc.DefaultViewPageActivator.Create(ControllerContext controllerContext, Type type) +87
   System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +216
   Postal.EmailViewRenderer.RenderView(IView view, ViewDataDictionary viewData, ControllerContext controllerContext, ImageEmbedder imageEmbedder) +182
   Postal.EmailViewRenderer.Render(Email email, String viewName) +204
   Postal.EmailService.CreateMailMessage(Email email) +72
   Postal.EmailService.Send(Email email) +65

我对 Mvc.Unity4 不太熟悉,因为它是由其他开发人员添加的。

抓住最后一根稻草,我确实尝试在 Application_Start 中注册正确的邮政类型。 Unity容器的初始化发生在Bootstrapper.cs

container.RegisterType<UsersController>(new InjectionConstructor());
container.RegisterInstance<IEmailService>(new EmailService());

在我的控制器中,我有:

private IEmailService _emailService;
public UsersController()
{
    _emailService = new Postal.EmailService();
}

public UsersController(Postal.EmailService emailService)
{
    _emailService = emailService;
}

[HttpPost]
public async Task<ActionResult> SendEmail(EmailViewModel viewModel)
{
     dynamic e = new Email("AccountActivation");
     e.ViewData.Add("To", "name@email.com");
     e.ViewData.Add("From", "no-reply@email.com");
     _emailService.Send(e);

     More code...
}

【问题讨论】:

    标签: c# asp.net-mvc dependency-injection unity-container postal


    【解决方案1】:

    我认为你的怀疑是正确的。 HttpContext 在应用程序初始化期间不可用。因此 Postal 在Application_Start 事件中不起作用(因为它依赖于ControllerContextViewContext)。

    由于您使用的是 DI,因此这也扩展到使用 Unity 配置的每个类的构造函数 - 您不能在构造函数中使用 Postal,但可以在 Application_Start 完成后调用的方法中使用。

    您需要将调用移至 Application_Start 之外的 Postal,或者在这种情况下使用本机 .NET 邮件库(因为它们依赖于 System.Net 并且不依赖于 HttpContext)。

    【讨论】:

    • 澄清一下,我创建和发送 Postal 电子邮件的调用确实驻留在 Application_Start 之外的控制器中。我只是尝试在 Application_Start 中注册 Postal 对象,并在 Application_Start 运行后使用控制器中的电子邮件代码。
    • 请发布 postal 及其所有依赖项的相关 DI 配置。
    【解决方案2】:

    很抱歉回答我自己的问题,但我终于能够得到这个工作。

    一旦我从方法中删除了async,一切都开始按预期工作。

    所以通过改变...

    public async Task<ActionResult> SendEmail(EmailViewModel viewModel)
    

    到这里……

    public ActionResult SendEmail(EmailViewModel viewModel)
    

    然后我能够发送电子邮件而不会触发 Unity.Mvc4.UnityDependencyResolver.get_ChildContainer() 内的异常。

    我不知道为什么我不能从 async 方法中调用 Postal 的 .Send()(请注意,我尝试调用 .SendAsync() 时会出现同样的 Unity 问题)。如果有人能解释为什么这会在 async 方法中起作用,将不胜感激。

    谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多