Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autofac property injection in base class

I am working on a Windows Phone 8.1 application and I have a base class with public property.

public class ViewModelBase
{
   public ISomeClass MyProp {get;set;}
}

My derived class looks like this

public class MainViewModel : ViewModelBase
{
    private readonly INavigation _navigation;
    public MainViewModel(INavigation navigation)
    {
        _navigation = navigation;
    }
}

In my App.cs I have

 var builder = new ContainerBuilder();
 builder.RegisterType<Navigation>().As<INavigation>();
 builder.RegisterType<SomeClass>().As<ISomeClass>();
 builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());

When MainViewModel is created my INavigation is resolved but MyProp is null. I have tried

builder.Register(c => new ViewModelBase { MyProp = c.Resolve<ISomeClass>() });

builder.Register(c => new ViewModelBase()).OnActivated(e => e.Instance.MyProp = e.Context.Resolve<ISomeClass>());

builder.RegisterType<ViewModelBase>().PropertiesAutowired();

but none of it works!

Solution posted here http://bling.github.io/blog/2009/09/07/member-injection-module-for-autofac/

works but I don't like it :)

I don't want to use constructor injection in this case.

Thank you.

like image 447
partyelite Avatar asked Nov 07 '14 18:11

partyelite


People also ask

What is AutoFac dependency injection?

Autofac is an addictive IoC container for . NET. It manages the dependencies between classes so that applications stay easy to change as they grow in size and complexity. This is achieved by treating regular . NET classes as components.

Why should I use AutoFac?

AutoFac provides better integration for the ASP.NET MVC framework and is developed using Google code. AutoFac manages the dependencies of classes so that the application may be easy to change when it is scaled up in size and complexity.


2 Answers

This will load up all classes that inherit ViewModelBase and inject only the specific properties that you want. A lot of the time, you don't want the other properties on the child class to be injected.

builder.RegisterAssemblyTypes( GetType().Assembly )
    .AssignableTo<ViewModelBase>()
    .OnActivated( args =>
    {
        var viewModel = args.Instance as ViewModelBase;
        if( viewModel != null )
        {
            viewModel.MyProp = args.Context.Resolve<ISomeClass>();
        }
    } );
like image 133
Josh Close Avatar answered Oct 14 '22 18:10

Josh Close


You must make sure that your viewmodel class, MainViewModel, is registered with property injection. Currently, all you have registered with property injection is ViewModelBase, but think about what you are resolving. You will never resolve ViewModelBase, you're resolving MainViewModels. So that is what needs to be registered in the container.

Try:

builder.RegisterType<MainViewModel>().PropertiesAutowired();
like image 37
Peter Lillevold Avatar answered Oct 14 '22 17:10

Peter Lillevold