Chèn phụ thuộc không hàm ý các hàm tạo tham số. Trong thực tế, nếu bạn nhìn vào các mẫu đi kèm với Unity, hầu hết việc tiêm phụ thuộc được thực hiện bởi các thuộc tính với thuộc tính [Dependency].
Unity hoạt động rất tốt với XAML, nhưng chỉ khi bạn không sử dụng các nhà thầu được tham số hóa. Chuyển đổi UserControl của bạn để sử dụng các thuộc tính của nó bằng thuộc tính [Dependency] và bạn có thể dễ dàng sử dụng 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));
...
}
Lưu ý rằng thuộc tính [Phụ thuộc] có thể được khai báo dưới dạng Thuộc tính phụ thuộc hoặc thuộc tính CLR đơn giản như được hiển thị ở trên. Điều này nghe có vẻ như danh pháp khó hiểu nhưng trong thực tế nó rất đơn giản.
Để xác định UnityContainer trong XAML và nhận được cấu hình tự động, chỉ cần tạo một tài sản gắn liền thừa hưởng "UnityHelper.Container" mà PropertyChangedCallback chỉ đơn giản gọi tích tụ trên thùng sơn quy định và vượt qua trong loại của đối tượng và đối tượng:
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);
}
}
});
}
Bây giờ bạn có thể gán một UnityContainer để cửa sổ thư mục gốc của bạn và toàn bộ ứng dụng của bạn sẽ sử dụng nó, ví dụ bạn có thể làm điều đó trong constructor của cửa sổ của bạn như sau:
UnityHelper.SetContainer(this, new UnityContainer() ...);
Hoặc bạn có thể gán container thống nhất sử dụng XAML tại bất kỳ mức độ mong muốn của cây:
<UserControl ...
my:UnityHelper.Container="{DynamicResource MainUnityContainer}" />
Có nói tất cả điều đó, tôi nghĩ rằng bạn sẽ sẽ thấy rằng dữ liệu tiên tiến WPF của tính năng và từ điển tài nguyên ràng buộc cùng nhau loại bỏ 98% trong những lý do tại sao một người đó có thể muốn sử dụng Unity ngay từ đầu. Bạn có thể tìm thấy nó tốt hơn trong thời gian dài để di chuyển ra khỏi Unity và đi với MVVM đơn giản. Ít nhất tôi sẽ thử MVVM thuần túy trên một ứng dụng thử nghiệm để xem nó hoạt động như thế nào trước khi phát triển nhiều mã dựa vào Unity để tiêm phụ thuộc.
nó hoạt động, nhưng khi tôi nhấn nút tab từ một trong các hộp văn bản nó ném ngoại lệ Độ phân giải của phụ thuộc không thành công, type = "System.Windows.Input.KeyboardNavigation + FocusVisualAdorner", name = "". Thông báo ngoại lệ là: Hoạt động xây dựng hiện tại (khoá xây dựng Khóa [System.Windows.Input.KeyboardNavigation + FocusVisualAdorner, null]) không thành công: Không thể tải loại 'System.Windows.Input.KeyboardNavigation' từ assembly 'PresentationFramework, Version = 3.0 .0.0, Văn hóa = trung lập, PublicKeyToken = 31bf3856ad364e35 '. (Chiến lược loại BuildPlanStrategy, chỉ số 5) – Miral
Câu trả lời này đã giúp tôi rất nhiều. Tôi ước tôi có thể cung cấp nhiều hơn +1. Tôi đã thêm chủ đề này vào "Mục yêu thích của tôi", nhưng điều đó chỉ ghi nhận anh chàng hỏi câu hỏi gốc. Cảm ơn! – Tormod
Nếu bạn tạo một giao diện (gọi là IUnityElement) mà bạn áp dụng cho tất cả các UserControls hoặc Điều khiển, bạn cần thống nhất để chạy ngược lại trong dòng 'if (container! = Null)', bạn có thể kiểm tra xem tham số obj có thuộc giao diện đó không ví dụ 'if (container! = null && obj is IUnityInject)'. Điều này loại bỏ lỗi mà Miral đã nhận xét ở trên (tôi nhận được một lỗi tương tự từ một đối tượng khác và vấn đề về hiệu suất của câu trả lời ZeePrime, vì BuildUp chỉ chạy trên FrameworkElements mà bạn cần nó. –