I'm building a WPF application and using Autofac as an IoC container. The scenario is kind of hard to describe but I'll try to give the relevant piece of code below:
My app bootstrapper contains the following code to register the viewmodels in my app:
builder.RegisterAssemblyTypes(assemblySource)
.Where(type => type.Name.EndsWith("ViewModel"))
.Where(type => !string.IsNullOrWhiteSpace(type.Namespace) && type.Namespace.Contains("ViewModels"))
.AssignableTo<INotifyPropertyChanged>()
.AsSelf()
.InstancePerDependency();
(note the InstancePerDependency()
call, which I have to make, because I display many instances of a view)
Then I have the following code to register implementers of an open generic:
builder.RegisterAssemblyTypes(assemblySource)
.AsClosedTypesOf(typeof(INotificationHandler<>))
.AsSelf()
.SingleInstance();
To avoid passing the container into my event dispatcher, I'm passing it instead a delegate as follows:
builder.Register<ServiceFactory>(ctx => { return t => Container.Resolve(t ); });
And the last bit of code is causing me a problem: It's causing the ViewModels that implement the INotificationHandler
interface to have instances created on every call, while I need only once instance to be resolved, and the ViewModels implement this generic interface will have only one instance created throughout the application.
Question is: How can I make Autofac resolve single instances of the ViewModels that Implement the INotificationHandler<T>
interface, while keeping the other ViewModels to be created PerDependency
?
Thanks.
You need to exclude ViewModels that implements INotificationHandler<> in your first registration. So change your first registration to:
builder.RegisterAssemblyTypes(Assembly.GetEntryAssembly())
.Where(type => type.Name.EndsWith("ViewModel"))
.Where(type => !string.IsNullOrWhiteSpace(type.Namespace) && type.Namespace.Contains("ViewModels"))
.Where(type => !type.IsAssignableFrom(typeof(INotificationHandler<>)))
.AssignableTo<INotifyPropertyChanged>()
.AsSelf()
.InstancePerDependency();