Dan
Dan

Reputation: 1745

How to resolve property injection with Autofac?

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:

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>();

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.

Upvotes: 3

Views: 8575

Answers (3)

Jamee
Jamee

Reputation: 121

hmm your example is wrong because AliasesService does not implement Interface IAliasesService, but I think that's a typo.

Your MAilService implementation is missing. PropertiesAutowired() silently fails if there are dependencies that it can't resolve.

So your problem probably lies in MailService

Upvotes: 0

Jacek Gorgoń
Jacek Gorgoń

Reputation: 3214

Your minimal example works fine, Foo resolves with a Bar instance injected.

While it's not too helpful, your problem lies elsewhere.

Upvotes: 1

Cyril Durand
Cyril Durand

Reputation: 16187

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>();

Upvotes: 1

Related Questions