3

I want to inject DispatcherNotifiedObservableCollection into (and only into) all ViewModels (located in MyProject.ViewModels) as ObservableCollection.

With Ninject I can accomplish this with:

Bind(typeof(ObservableCollection<>))
    .To(typeof(DispatcherNotifiedObservableCollection<>))
    .When(context => context.ParentContext.Binding
        .Service.Namespace == "MyProject.ViewModels");

I've learned from Nicholas Blumhardt: Autofac vs Ninject contextual binding?

that Autofac does not provide this functionality, but some workaround could be applied.

Thanks!

(sorry for my English)

Edit 1: Changed title for better description.

Edit 2, 3: Changed contents and title for better description.

Community
  • 1
  • 1

1 Answers1

8

Sorry about the slow reply.

Your best bet with Autofac is to use a rule for registering the ViewModels and to apply a parameter to resolve the different implementation of ObservableCollection<>:

// Default for other components
builder.RegisterGeneric(typeof(ObservableCollection<>));

// Won't be picked up by default
builder.RegisterGeneric(typeof(DispatcherNotifiedObservableCollection<>))
    .Named("dispatched", typeof(ObservableCollection<>));

var viewModelAssembly = typeof(AViewModel).Assembly;
builder.RegisterAssemblyTypes(viewModelAssembly)
    .Where(t => t.Name != null && t.Name.EndsWith("ViewModel"))
    .WithParameter(
        (pi, c) => pi.ParameterType.IsClosedTypeOf(typeof(ObservableCollection<>)),
        (pi, c) => c.ResolveNamed("dispatched", pi.ParameterType));

You'll need to be using Autofac; for IsClosedTypeOf(). Also, if the version of Autofac you're using doesn't support this overload of WithParameter() you can use the overload that takes a Parameter and pass a ResolvedParameter instead.

Hope this helps,

Nick

Nicholas Blumhardt
  • 30,271
  • 4
  • 90
  • 101