【问题标题】:How to resolve property injection with Autofac?如何使用 Autofac 解决属性注入?
【发布时间】:2015-04-14 09:45:47
【问题描述】:

我有一个 MVC Web 应用程序,它使用 Autofac 在控制器中注入服务。

问题:我正在尝试对服务进行属性注入,但它失败了(该属性始终为空)。

我的期望: 我希望 Autofac 正确初始化属性(不为空)。

示例:

  • 我正在尝试将 AliasesService 作为 IAliasesService 注入到控制器中。
  • AliasesService 依赖于 MailService。
  • MailService 是 AliasesService 的一个属性。
  • AliasesService 已正确实例化并传递给 MyController。
  • MailService 未正确实例化并设置为 AliasesService 的属性

控制器:

public class MyController: Controller
{
    private IAliasesService AliasesService { get; set; }

    public MyController(IAliasesService aliasesService)
    {
        AliasesService = aliasessService;
    }

    public ActionResult Index()
    {
        var model = aliasesService.GetUserRoles();

        return View();
    }
}

全球.asax:

var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();

builder.RegisterType<MailService>().As<IMailService>();
builder.RegisterType<AliasesService>().As<IAliasesService>().PropertiesAutowired();

var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

别名服务:

public class AliasesService
{
     public IMailService MailService { get; set; }

     public Dictionary<int,string> GetUserRoles()
     {
          MailService.SendMail("method GetUserRoleshas been called");
          return null;
     }
}

值得一提:

  • 如果我尝试为控制器进行属性注入,它会按预期工作
  • 构造函数注入有效,但我需要属性注入。

我尝试了哪些其他方法但没有成功:

1

builder.RegisterType<MailService>()
       .As<IMailService>();
builder.Register(c => new AliasesService() 
       { 
           MailService = c.Resolve<IMailService>() 
        })
       .As<IAliasesService>();

2

builder.RegisterType<MailService>()
       .As<IMailService>();
builder.RegisterType<AliasesService>()
       .WithProperty("MailService", new MailService())
       .As<IAliasesService>();

简单示例:

using Autofac;

namespace ConsoleApplication1
{
    public interface IBar
    {    
    }

    public class Bar: IBar
    {
        public string Text { get; set; }

        public Bar()
        {
            Text = "Hello world!";
        }
    }

    public interface IFoo
    {
    }

    public class Foo: IFoo
    {
        public IBar Bar { get; set; }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = new ContainerBuilder();

            builder.RegisterType<Bar>().As<IBar>();
            builder.RegisterType<Foo>().As<IFoo>().PropertiesAutowired();

            var container = builder.Build();

            var foo = container.Resolve<IFoo>();
        }
    }
}

替代解决方案:

对于 Autofac 的最小示例,但在控制器的上下文中,我仍然没有设法使其按预期工作,所以我放弃了使用它,因为我浪费了太多时间。我目前正在使用 Castle Windsor,它可以满足我的一切需求,感谢您的支持。

【问题讨论】:

  • 什么不起作用?您的代码看起来没有问题(除了您有多个相同抽象的注册)。发布一个简短但完整的示例来演示该问题。 MailService 属性的类型是什么? MailServiceIMailService ?
  • MailServiceDbRespositoryAliasesService 的属性? (我认为这是您的代码示例中的错误)。所有尝试过的解决方案都应该有效。你能分享你的控制器和服务的代码吗? (只有构造函数和属性)
  • 上面的陈述是我尝试过的。我得到一个空引用而不是一个必需的实例。
  • DbRepository 只是 AliasesService 的另一个依赖项,由构造函数满足。我正在简化代码。
  • 例如,使用这一行:builder.RegisterType() .As() .PropertiesAutowired();查看文档,它应该可以解决问题,但它不是因为在运行时我在 AliasesService 中的属性 MailService 具有“null”值。

标签: c# model-view-controller dependency-injection autofac property-injection


【解决方案1】:

在您的最小代码示例中,属性 Bar 声明为未注册的 Bar 类型。为了让 Autofac 解析它,应该注册声明的属性类型。您应该将属性的类型更改为IBar 或将Bar 注册为Bar

public class Foo : IFoo
{
    public IBar Bar { get; set; }
}

builder.RegisterType<Bar>().As<Bar>();

【讨论】:

  • 这是真的,但是最小repro与上面注入IMailService(不是MailService)的AliasesService代码不一致。 @user2704:请说明您使用的是哪个代码被剪断。另外,您可以使用AsSelf()
  • 这是一个错字,我更正了代码并添加了更多细节。谢谢大家的支持。
【解决方案2】:

您的最小示例运行良好,Foo 通过注入 Bar 实例解析。

虽然没有太大帮助,但您的问题出在其他地方。

【讨论】:

    【解决方案3】:

    嗯,您的示例是错误的,因为 AliasesService 没有实现接口 IAliasesService,但我认为这是一个错字。

    您的 MAilService 实现丢失。如果存在无法解析的依赖项,PropertiesAutowired() 会静默失败。

    所以你的问题可能出在 MailService 上

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-26
      • 1970-01-01
      • 2012-09-21
      • 1970-01-01
      相关资源
      最近更新 更多