Đây là giải pháp của tôi. Lúc đầu, tôi đã thử tạo một phương thức mở rộng. Tôi đã thử nhiều thứ, đọc tài liệu và khám phá các thuộc tính, sự kiện và phương pháp sẵn có trên thùng chứa và danh mục, nhưng tôi không thể làm được gì.
Sau khi suy nghĩ về vấn đề, cách duy nhất tôi có thể đưa ra giải pháp là tạo một thùng chứa có nguồn gốc dựa trên CompositionContainer và triển khai phương thức GetButDoNotCreate.
Cập nhật: Tôi nhận ra sau khi đăng nó rằng giải pháp chỉ hoạt động trong ví dụ đơn giản mà bạn đã đăng ở đó chỉ GetExportedValue được sử dụng để truy xuất các phần đơn giản. Trừ khi bạn sử dụng vùng chứa làm định vị dịch vụ đơn giản cho các phần không có [Nhập] mà sẽ không thực hiện khi các phần có [Nhập] được tạo.
Đây là việc thực hiện:
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
namespace GetButNotCreate
{
public class CustomContainer : CompositionContainer
{
private List<Type> composedTypes = new List<Type>();
public CustomContainer(ComposablePartCatalog catalog)
: base(catalog)
{
}
public new T GetExportedValue<T>()
{
if (!composedTypes.Contains(typeof(T)))
composedTypes.Add(typeof(T));
return base.GetExportedValue<T>();
}
public T GetButDoNotCreate<T>()
{
if (composedTypes.Contains(typeof(T)))
{
return base.GetExportedValue<T>();
}
throw new Exception("Type has not been composed yet.");
}
}
}
Nó hoạt động bằng cách ghi đè các phương pháp GetExportedValue để theo dõi các loại đã được sáng tác cho đến nay và sau đó sử dụng này để kiểm tra các loại thành phần trong GetButNotCreate. Tôi đã ném một ngoại lệ như bạn đã đề cập trong câu hỏi của bạn. Tất nhiên, bạn có thể cần phải ghi đè lên quá tải của GetExportedValue (trừ khi bạn không sử dụng chúng, nhưng ngay cả như vậy, tôi sẽ ghi đè lên chúng cho an toàn) và có thể thêm các nhà xây dựng khác và các công cụ nếu bạn sử dụng lớp học. Các tính năng chính của chúng tôi là an toàn. Trong ví dụ này, tôi đã làm tối thiểu để làm cho nó hoạt động.
Dưới đây là các bài kiểm tra đơn vị thử nghiệm phương pháp mới:
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
namespace GetButNotCreate
{
public interface IInterface { }
[Export(typeof(IInterface))]
public class MyClass : IInterface
{
}
[TestClass]
public class UnitTest1
{
[TestMethod]
[ExpectedException(typeof(Exception), "Type has not been composed yet.")]
public void GetButNotCreate_will_throw_exception_if_type_not_composed_yet()
{
var catalog = new AssemblyCatalog(typeof(UnitTest1).Assembly);
CustomContainer container = new CustomContainer(catalog);
container.ComposeParts(this);
var test = container.GetButDoNotCreate<IInterface>();
}
[TestMethod]
public void GetButNotCreate_will_return_type_if_it_as_been_composed()
{
var catalog = new AssemblyCatalog(typeof(UnitTest1).Assembly);
CustomContainer container = new CustomContainer(catalog);
container.ComposeParts(this);
var x = container.GetExportedValue<IInterface>();
var y = container.GetButDoNotCreate<IInterface>();
Assert.IsNotNull(y);
Assert.AreEqual(x, y);
}
}
}
Nó cho thấy rằng GetButNotCreate sẽ ném một ngoại lệ nếu loại chưa bao giờ được xuất khẩu và rằng nó sẽ trở lại loại này nếu nó đã được đã nhập.
Tôi không thể tìm thấy bất kỳ móc nào để kiểm tra (mà không cần phải phản ánh) để xem liệu MEF có bao gồm một phần hay không, vì vậy giải pháp CustomContainer này sẽ là đặt cược tốt nhất của tôi.
Tôi sẽ hỏi tại sao bạn dường như đang thử nghiệm vùng chứa trong các thử nghiệm đơn vị của mình? –
@MatthewAbbott - Tôi đang cố gắng viết các kiểm tra hệ thống ở lớp ViewModel (được xây dựng với thiết kế đầu tiên của ViewModel). Đây không phải là bài kiểm tra đơn vị ... Thay vì thao tác các phần tử giao diện người dùng, tôi muốn tiếp cận vào vùng chứa, lấy khung nhìn và đạt được hiệu ứng tương tự. – Gishu
Thêm ngữ cảnh tại đây - http://caliburnmicro.codeplex.com/discussions/348548 – Gishu