3

I am using Autofac with MVC / Owin and WebApi.

Following Autofac documentation I am using the setup:

public static void Run(IAppBuilder application) {

  ContainerBuilder builder = new ContainerBuilder();

  HttpConfiguration configuration = GlobalConfiguration.Configuration;

  builder.RegisterControllers(typeof(MvcApplication).Assembly);
  builder.RegisterModelBinders(typeof(MvcApplication).Assembly);
  builder.RegisterModelBinderProvider();
  builder.RegisterModule<AutofacWebTypesModule>();
  builder.RegisterSource(new ViewRegistrationSource());
  builder.RegisterFilterProvider();
  builder.RegisterApiControllers(typeof(MvcApplication).Assembly);
  builder.RegisterWebApiFilterProvider(configuration);

  builder.RegisterType<Test>().As<ITest>().PropertiesAutowired();        

  IContainer container = builder.Build();
  application.UseAutofacMiddleware(container);
  DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
  configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);

}

I then tested constructor and property injection on a controller:

public interface ITest { }
public class Test : ITest { }

public partial class HomeController : Controller {

  private ITest _testConstructor { get; set; }
  public ITest TestProperty { get; set; }

  public HomeController(ITest testConstructor) {

    _testConstructor = testConstructor;

  }

  public virtual ActionResult Index() {
    var test = TestProperty;
  }
}

So _testConstructor is injected and TestProperty is always null.

I even checked its value inside Index method and it is null ...

I tried different configurations and in different parts of the application and Property injection always fails ...

Can someone, please, help me out with this?

Update 1

Adding .PropertiesAutowired(); to RegisterController work for controllers but not for ViewPages.

I am using a ViewPageBase as follows:

public abstract class ViewPageBase : WebViewPage {
  public ITest Test { get; set; }
} // ViewPageBase

public abstract class ViewPageBase<T> : WebViewPage<T> {
  public ITest Test { get; set; }
} // ViewPageBase

And then in Autofac setup I have:

builder.RegisterSource(new ViewRegistrationSource());
builder.RegisterType<Test>().As<ITest>();
builder.RegisterType<WebViewPage>().PropertiesAutowired();
builder.RegisterGeneric(typeof(WebViewPage<>)).PropertiesAutowired();

But when I access Test properties in my views it is null.

Why?

Update 2

If in my layout view I add:

@{
  var test = DependencyResolver.Current.GetService<ITest>();
}

test is resolved correctly ...

Maybe is this a problem with Layout Pages and Autofac?

Update 3

I was able to replicate the problem and created a project in https://github.com/mdmoura/MvcAutofac

If you run the project there will be an error on _Layout master page on the second code line:

  @SettingsA.Get()
  @SettingsB.Get()

SettingsA is resolved in ViewPagePage using DependencyResolver and it works.

With SettingsB i am trying to use Property Injection and no luck.

Autofac configuration is in global.asax Application_Start.

Does anyone knows what might be wrong?

Miguel Moura
  • 36,732
  • 85
  • 259
  • 481

1 Answers1

8

Properties injection is not done automatically in Autofac. You have to tell Autofac to inject properties on your controller registration.

builder.RegisterControllers(typeof(MvcApplication).Assembly)
       .PropertiesAutowired();

See Property and Method Injection for more information on autowiring properties.

Cyril Durand
  • 15,834
  • 5
  • 54
  • 62
  • that worked for controllers but not for Views. I added updated my question in relation to Views injections. Could you please check it out? – Miguel Moura Apr 09 '15 at 10:57
  • I just read this article http://alexmg.com/view-page-injection-in-autofac-aspnet-mvc-3-integration/ and it seems that you don't have to register your `WebViewPage` if you use the `ViewRegistrationSource`. Could you try removing the 2 `WebViewPage` registrations ? – Cyril Durand Apr 09 '15 at 11:12
  • Yes, I get the same problem ... In fact I added the WebViewPage because ViewReistrationSource didn't solved it for me ... – Miguel Moura Apr 09 '15 at 11:15
  • I tried `ViewRegistrationSource` on a local project and it works fine for me : no need to register any `ViewPage` and my properties are not null. Could you confirm that you register it before `container.Build();` – Cyril Durand Apr 09 '15 at 12:30
  • Yes, I registered it before container.Build() and in Web.Config I have which seems to work because I am able to access the properties in my Views. So I really have no idea where to look for the problem. – Miguel Moura Apr 09 '15 at 13:34
  • Is this maybe a problem that Autofac has with Layout Views? – Miguel Moura Apr 09 '15 at 13:50
  • It looks like *Autofac* is not used to instanciate your *ViewPage*. Could you add an ampty constructor on your *ViewPage*, add a breakpoint and look at the stack trace to ensure that Autofac is creating the instance? – Cyril Durand Apr 09 '15 at 14:11
  • I added a contructor as you asked and it is not fired ... Any idea why? The strange thing is that I had this working fine with StructureMap ... So it might be something with my Autofac configuration. – Miguel Moura Apr 09 '15 at 15:27
  • I just updated my question (Update 3) and added a project using the default MVC template where I was able to replicate the problem. Could you, please, take a look? Repository is here: https://github.com/mdmoura/MvcAutofac. Thank You. – Miguel Moura Apr 09 '15 at 22:29
  • 1
    It seems that DependencyResolver is not involved by ASP.net MVC for layout : you can't have property injection inside layout, you'll have to use `DependencyResolver` manually on constructor see http://stackoverflow.com/questions/11593580/can-autofac-inject-dependencies-into-layout-view-files and http://code.google.com/p/autofac/issues/detail?id=349#hc9 for more information – Cyril Durand Apr 09 '15 at 23:12