3

我有一个 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,它可以满足我的一切需求,感谢您的支持。

4

3 回答 3

1

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

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

或者

builder.RegisterType<Bar>().As<Bar>();
于 2015-04-15T17:01:43.620 回答
1

您的最小示例工作正常, Foo 通过注入 Bar 实例解析。

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

于 2015-04-17T09:11:27.653 回答
0

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

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

所以你的问题可能出在 MailService

于 2016-01-15T15:48:11.167 回答