Die Abhängigkeitsinjektion impliziert keine parametrisierten Konstruktoren. Wenn Sie sich die Samples ansehen, die mit Unity geliefert werden, erfolgt der Großteil der Abhängigkeitsinjektion durch Eigenschaften mit dem [Dependency] -Attribut.
Unity funktioniert sehr gut mit XAML, aber nur, wenn Sie keine parametrisierten Konstruktoren verwenden. Konvertieren Sie Ihr UserControl, um seine Abhängigkeiten mithilfe von Eigenschaften mit dem Attribut [Dependency] zu übernehmen, und Sie können XAML problemlos verwenden.
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));
...
}
Beachten Sie, dass eine [Abhängigkeit] Eigenschaft kann entweder als DependencyProperty oder als einfache CLR-Eigenschaft deklariert werden, wie oben gezeigt. Das klingt nach einer verwirrenden Nomenklatur, ist aber in der Praxis sehr einfach. PropertyChangedCallback ruft einfach Anhaftungen an dem angegebenen Container
Um die UnityContainer in XAML angeben und die automatische Konfiguration erhalten, nur eine vererbte angefügten Eigenschaft „UnityHelper.Container“, deren erstellen und leitet in dem Objekttyp und das Objekt:
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);
}
}
});
}
Jetzt können Sie einen UnityContainer zu Ihrem root-Fenster zuweisen und Ihre gesamte Anwendung wird es verwenden, zum Beispiel Sie es in Ihrem Fenster Konstruktor tun könnte wie folgt:
UnityHelper.SetContainer(this, new UnityContainer() ...);
Oder Sie können zuweisen XAML an einer beliebigen Ebene des Baums der Behälter Einheit mit:
<UserControl ...
my:UnityHelper.Container="{DynamicResource MainUnityContainer}" />
alles, was gesagt hat, ich glaube, Sie werden feststellen, dass WPF fortschrittliche Datenbindung Features und Ressourcen Wörterbücher zusammen 98% der Gründe zu beseitigen, warum ein Die Person möchte möglicherweise zuerst Unity verwenden. Sie können es auf lange Sicht besser finden, sich von Unity zu entfernen und mit einfachem MVVM zu arbeiten. Zumindest würde ich reines MVVM in einer Testanwendung ausprobieren, um zu sehen, wie es funktioniert, bevor viel Code entwickelt wird, der auf Unity für die Abhängigkeitsinjektion angewiesen ist.
es funktioniert, aber wenn ich auf die Schaltfläche Tab getroffen von einem Textfeld wirft es Ausnahme Auflösung der Abhängigkeit ist fehlgeschlagen, type = „System.Windows.Input.KeyboardNavigation + FocusVisualAdorner“ name = „“. Ausnahmebedingungsnachricht lautet: Die aktuelle Erstellungsoperation (Buildschlüssel Erstellungsschlüssel [System.Windows.Input.KeyboardNavigation + FocusVisualAdorner, null]) ist fehlgeschlagen: Der Typ 'System.Windows.Input.KeyboardNavigation' konnte nicht von der Assembly 'PresentationFramework, Version = 3.0' geladen werden .0.0, Kultur = neutral, PublicKeyToken = 31bf3856ad364e35 '. (Strategie Typ BuildPlanStrategy, Index 5) – Miral
Diese Antwort hat mir enorm geholfen. Ich wünschte, ich könnte mehr als +1 geben. Ich habe diesen Thread zu "Meine Favoriten" hinzugefügt, aber das wird nur dem Typen gutgeschrieben, der die ursprüngliche Frage gestellt hat. Also vielen Dank! – Tormod
Wenn Sie eine Schnittstelle erstellen (IUnityElement genannt), die Sie auf alle Benutzersteuerelemente oder Steuerelemente anwenden, für die Sie Unity ausführen müssen, können Sie in der Zeile 'if (container! = Null)' überprüfen, ob der Parameter obj dieser Schnittstelle entspricht z.B 'if (container! = null && obj ist IUnityInject)'. Dies beseitigt den oben erwähnten Fehler Miral (ich habe einen ähnlichen von einem anderen Objekt und das Performance-Problem von ZeePrime bekommen, da das BuildUp nur auf FrameworkElements ausgeführt wird, für die es benötigt wird. –