I have an MVC web app which uses Autofac to inject services in controllers.
The problem: I am trying to do property injection on a service and it fails (the property is always null).
What I expect: I expect to have the property initialized properly (not null) by Autofac.
Example:
Controller:
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;
}
}
Worth mentioning:
What other things I tried with no success:
builder.RegisterType<MailService>()
.As<IMailService>();
builder.Register(c => new AliasesService()
{
MailService = c.Resolve<IMailService>()
})
.As<IAliasesService>();
builder.RegisterType<MailService>()
.As<IMailService>();
builder.RegisterType<AliasesService>()
.WithProperty("MailService", new MailService())
.As<IAliasesService>();
Minimal example:
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>();
}
}
}
Alternative solution:
For the minimal example Autofac works but in the context of controllers I still did not managed to make it work as expected so I gave up on using it as I wasted too much time. I'm using Castle Windsor for now and it does everything I need, thank you for the support.
On your minimal code sample the property Bar is declared of type Bar
which is not registered. The declared property type should be registered in order to let Autofac resolve it. You should change the type of the property to IBar
or register Bar
as Bar
public class Foo : IFoo
{
public IBar Bar { get; set; }
}
or
builder.RegisterType<Bar>().As<Bar>();