Используйте Autofac для внедрения зависимостей в конкретное пространство имен - PullRequest
3 голосов
/ 31 января 2011

Я хочу внедрить DispatcherNotifiedObservableCollection в (и только в) все ViewModels (расположенные в MyProject.ViewModels) как ObservableCollection.

С помощью Ninject я могу сделать это с помощью:

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

IВы узнали от Николаса Блюмхардта: Autofac vs Ninject контекстная привязка?

, что Autofac не предоставляет эту функциональность, но может быть применен некоторый обходной путь.

Спасибо!

(извините за мой английский)

Редактировать 1: измененное название для лучшего описания.

Редактировать 2, 3: измененное содержание и название для лучшего описания.

1 Ответ

8 голосов
/ 01 февраля 2011

Извините за медленный ответ.

Лучше всего в Autofac использовать правило для регистрации ViewModel s и применить параметр для разрешения другой реализации 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));

Вам нужно быть using Autofac; для IsClosedTypeOf().Кроме того, если используемая вами версия Autofac не поддерживает эту перегрузку WithParameter(), вы можете использовать перегрузку, которая принимает Parameter и вместо нее передает ResolvedParameter.

Надеюсь, это поможет,

Ник

...