Wpf usercontrol с параметризованным конструктором

Мы используем Microsoft Unity и внедрение зависимости и таким образом, мы параметризовали конструктора для usercontrol. Как ввести эту зависимость в usercontrol, использующий XAML?

Я добавил usercontrol в XAML как ниже.

xmlns:usrRefundArrivalProcessor="Ttl.Refunds.Wpf.Dashboad.Application.Usercontrols;assembly=Ttl.Refunds.Wpf.Dashboad.Application"
5
задан Miral 4 May 2010 в 10:48
поделиться

2 ответа

Внедрение зависимостей не подразумевает параметризованные конструкторы. Фактически, если вы посмотрите на образцы, поставляемые с Unity, большая часть внедрения зависимостей выполняется свойствами с атрибутом [Dependency].

Unity очень хорошо работает с XAML, но только если вы не используете параметризованные конструкторы. Преобразуйте свой UserControl, чтобы он принимал его зависимости, используя свойства с атрибутом [Dependency], и вы можете легко использовать XAML.

public class MyUserControl : UserControl
{
  [Dependency]
  public ISomething Something { get; set; }

  [Dependency]
  public IWhatever Whatever { get { return (IWhatever)GetValue(WhateverProperty); } set { SetValue(WhateverProperty, value); }
  public readonly DependencyProperty WhateverProperty = DependencyProperty.Register("Whatever", typeof(IWhatever), typeof(MyUserControl));

  ...
}

Обратите внимание, что свойство [Dependency] может быть объявлено либо как DependencyProperty, либо как простое свойство CLR, как показано выше. Это звучит как запутанная номенклатура, но на практике это очень просто.

Чтобы указать UnityContainer в XAML и получить автоматическую конфигурацию, просто создайте унаследованное присоединенное свойство «UnityHelper.Container», PropertyChangedCallback которого просто вызывает BuildUp в указанном контейнере и передает тип объекта и объект:

public class UnityHelper
{
  public static IUnityContainer GetContainer(DependencyObject obj) { return (IUnityContainer)obj.GetValue(ContainerProperty); }
  public static void SetContainer(DependencyObject obj, IUnityContainer value) { obj.SetValue(ContainerProperty, value); }
  public static readonly DependencyProperty ContainerProperty = DependencyProperty.RegisterAttached("Container", typeof(IUnityContainer), typeof(UnityHelper), new FrameworkPropertyMetadata
  {
    Inherits = true,
    PropertyChangedCallback = (obj, e) =>
    {
      var container = e.NewValue as IUnityContainer;
      if(container!=null)
      {
        var element = obj as FrameworkElement;
        container.BuildUp(obj.GetType(), obj, element==null ? null : element.Name);
      }
    }
  });
}

Теперь вы можете назначьте UnityContainer корневому окну, и все ваше приложение будет использовать его, например, вы можете сделать это в конструкторе вашего окна следующим образом:

UnityHelper.SetContainer(this, new UnityContainer() ...);

Или вы можете назначить контейнер единства с помощью XAML на любом желаемом уровне дерева:

<UserControl ...
  my:UnityHelper.Container="{DynamicResource MainUnityContainer}" />

Сказав все это, я думаю, вы обнаружите, что расширенные функции привязки данных и словари ресурсов WPF вместе устраняют 98% причин, по которым человек может захотеть использовать Unity в первую очередь. Возможно, в конечном итоге вам будет лучше отказаться от Unity и перейти на простой MVVM.По крайней мере, я бы попробовал чистый MVVM в тестовом приложении, чтобы увидеть, как оно работает, прежде чем разрабатывать много кода, полагающегося на Unity для внедрения зависимостей.

10
ответ дан 13 December 2019 в 22:03
поделиться

Кажется довольно простым. Почему бы просто не добавить "открытый конструктор без параметров" в UserControl? Вы можете не использовать его в своем коде напрямую, но это то, что ищет дизайнер. Если вы хотите убедиться, что он никогда не вызывается в коде, поставьте проверку на наличие Designer и выставьте исключение, если Designer не обнаружен.

0
ответ дан 13 December 2019 в 22:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: