This seems to work perfectly fine:
internal class Program
{
public static IContainer container;
public MyViewModel MyVM
{
get { return Program.container.Resolve<MyViewModel>(); }
}
private static void Main(string[] args)
{
ContainerBuilder containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<MyViewModel>();
container = containerBuilder.Build();
Program p = new Program();
MyViewModel vm = p.MyVM;
}
}
Do you have to use the AutoActivate? In other words, is there a specific need where you have to go through the constructor in the Build event?
From Autofac documentation:
An auto-activated component is a component that simply needs to be
activated one time when the container is built. This is a “warm start”
style of behavior where no method on the component is called and no
interface needs to be implemented - a single instance of the component
will be resolved with no reference to the instance held.
So this sounds to me, that if you use AutoActivation, the registered type will not be kept in the builders registry, so you would have to re-register it.
If you absolutely need it, than it must be registered twice:
internal class Program
{
public static IContainer container;
public MyViewModel MyVM
{
get { return Program.container.Resolve<MyViewModel>(); }
}
private static void Main(string[] args)
{
ContainerBuilder containerBuilder = new ContainerBuilder();
Console.WriteLine("Before register");
containerBuilder.RegisterType<MyViewModel>().AutoActivate();
containerBuilder.RegisterType<MyViewModel>();
container = containerBuilder.Build();
Program p = new Program();
Console.WriteLine("Before property retrieval");
MyViewModel vm = p.MyVM;
}
}
internal class MyViewModel
{
public MyViewModel()
{
Console.WriteLine("MyViewModel");
}
}
Result:
Before register
MyViewModel
Before property retrieval
MyViewModel
Press any key to continue . . .
If you need to run some code at startup, consider IStartable:
public class StartupMessageWriter : IStartable
{
public void Start()
{
Console.WriteLine("App is starting up!");
}
}
....
var builder = new ContainerBuilder();
builder
.RegisterType<StartupMessageWriter>()
.As<IStartable>()
.SingleInstance();
UPDATE
If you absolutely must, you could iterate through all the registrations:
foreach (var r in container.ComponentRegistry.Registrations)
{
var dump = container.ResolveComponent(r, Enumerable.Empty<Parameter>());
}
If your ViewModels implement a base class, you could use:
foreach (var r in container.ComponentRegistry.Registrations)
{
if (r.Target.Activator.LimitType.IsSubclassOf(typeof (ViewModel)))
{
var dump = container.ResolveComponent(r, Enumerable.Empty<Parameter>());
}
}
Dirty, but works.