Мы используем Microsoft Unity и внедрение зависимости и таким образом, мы параметризовали конструктора для usercontrol. Как ввести эту зависимость в usercontrol, использующий XAML?
Я добавил usercontrol в XAML как ниже.
xmlns:usrRefundArrivalProcessor="Ttl.Refunds.Wpf.Dashboad.Application.Usercontrols;assembly=Ttl.Refunds.Wpf.Dashboad.Application"
Внедрение зависимостей не подразумевает параметризованные конструкторы. Фактически, если вы посмотрите на образцы, поставляемые с 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 для внедрения зависимостей.
Кажется довольно простым. Почему бы просто не добавить "открытый конструктор без параметров" в UserControl
? Вы можете не использовать его в своем коде напрямую, но это то, что ищет дизайнер. Если вы хотите убедиться, что он никогда не вызывается в коде, поставьте проверку на наличие Designer и выставьте исключение, если Designer не обнаружен.