如何使用Autofac解决属性注入问题?

时间:2015-04-14 09:45:47

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

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

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

我的期望: 我希望通过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();
    }
}

的Global.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));

AliasesService:

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,它会完成我需要的一切,谢谢你的支持。

3 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:1)

你的最小例子工作正常,Foo解决了注入的Bar实例。

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

答案 2 :(得分:0)

嗯,你的例子是错误的,因为AliasesService没有实现Interface IAliasesService,但我认为这是一个错字。

缺少您的MAilService实施。如果存在无法解析的依赖项,PropertiesAutowired()将无提示失败。

所以你的问题可能在于MailService