2009-06-03 28 views
11

Hiện nay ứng dụng WPF tôi nhập khẩu một phần như thế nàyTạo nhiều trường hợp của linh kiện nhập khẩu MEF

[Import(typeof(ILedPanel)] 
public ILedPanel Panel { get; set; } 

Nhưng điều này mang đến cho ma một intance duy nhất của lớp mà thực hiện ILedPanel. Điều tôi thực sự muốn làm là có khả năng tạo ra nhiều trường hợp mà tôi cần. Xin lưu ý rằng chỉ có một lần xuất cho ILedPanel bao gồm với phần mềm tại bất kỳ thời điểm đã định nào.

(Nếu tôi sử dụng một khẩu với Danh sách đó mang lại cho tôi một ví dụ cho mỗi lớp thực hiện ILedPanel)

Bất kỳ lời đề nghị?

+0

Tôi không chắc đó là một cách hay nhưng tôi chỉ đơn giản là đi với Activator.CreateInstance (Panel.GetType()); – TimothyP

Trả lời

9

Có không phải là "xây dựng vào" hỗ trợ cho điều này trong MEF ngày hôm nay, nhưng trước khi quay trở lại Service Locator, bạn có thể tìm thấy một số nguồn cảm hứng ở đây: http://blogs.msdn.com/nblumhardt/archive/2008/12/27/container-managed-application-design-prelude-where-does-the-container-belong.aspx

Ý tưởng cơ bản là bạn 'nhập' vùng chứa vào thành phần cần thực hiện khởi tạo động.

Hỗ trợ trực tiếp khác cho kịch bản này là điều chúng tôi đang khám phá.

Nick

UPDATE: MEF hiện nay có hỗ trợ thử nghiệm cho việc này. Xem this blog post để biết thêm thông tin.

+0

cũng nếu tôi biết bạn sẽ tìm thấy câu hỏi tôi sẽ không nói bất cứ điều gì .... :) –

+1

CẬP NHẬT: tính năng này đã thực hiện theo cách của mình vào MEF "Xem trước 7" như PartCreator - xem wiki MEF để biết thông tin (http://mef.codeplex.com/Wiki/View.aspx?title=PartCreator&referringTitle=Home) –

+1

Nhưng chỉ cho Silverlight nó có vẻ là – TimothyP

2

tôi nghĩ bạn có nghĩa là bạn muốn sử dụng MEF trong trường hợp này như một định vị dịch vụ chứ không phải là thùng chứa phụ thuộc. Hãy thử nhìn vào ví dụ cho ValueResolver

10

Tôi không chắc chắn nếu điều này là những gì Nicolas là đề cập đến, nhưng bạn có thể import class Nhà máy chứ không phải là một lớp dụ, như thế này:

[Import(typeof(ILedPanelFactory)] 
public ILedPanelFactory PanelFactory { get; set; } 

... và sau đó trong mã của bạn ...

ILedPanel panel = PanelFactory.BuildPanel(); 
3

Nhìn vào mẫu hình dạng trò chơi mà đi kèm với MEF, có lớp ShapeFactory:

[Export] 
public class ShapeFactory 
{ 
    private readonly Random random = new Random((int)DateTime.Now.Ticks); 

    [Import] 
    private ICompositionService CompositionService { get; set; } 

    public IShape GetRandomShape() 
    { 
     var shapeRetriever = new ShapeRetriever(); 

     CompositionService.SatisfyImports(shapeRetriever); 

     int randomIndex = random.Next(shapeRetriever.PossibleShapes.Length); 

     return shapeRetriever.PossibleShapes[randomIndex].GetExportedObject(); 
    } 

    private class ShapeRetriever 
    { 
     [ImportMany(RequiredCreationPolicy = CreationPolicy.NonShared)] 
     public Export<IShape, IShapeMetadata>[] PossibleShapes { get; set; } 
    } 
} 

Điều này chứng tỏ việc tạo ra một thể hiện hình dạng ngẫu nhiên "theo yêu cầu" ... Tôi nghĩ trong kịch bản của bạn, bạn có thể làm một cái gì đó tương tự mà không cần lựa chọn ngẫu nhiên, như bạn đề nghị chỉ có một thực hiện ILedPanel đã đăng ký.

5

Trừ khi tôi hiểu sai câu hỏi, có vẻ như nó sẽ được giải quyết bằng cách đơn giản bằng cách sử dụng một CreationPolicy.NonShared.

Điều này giả định rằng mã khai báo Bảng điều khiển tồn tại ở mọi nơi bạn muốn có bảng điều khiển. Bạn sẽ nhận được một thể hiện mới của ILedPanel trong mọi trường hợp của mỗi lớp có khai báo này (việc nhập khẩu).

+0

Đúng vậy. Nhưng chỉ có một lớp thực hiện ILedPanel với bất kỳ phân phối phần mềm nào. Vì vậy, đó là một ví dụ duy nhất ... nó không sạch sẽ của khóa học – TimothyP

8

Tất cả các câu trả lời khác đều khá cũ nên không đề cập đến một tính năng tương đối mới trong MEF gọi là ExportFactory.lớp generic này cho phép bạn nhập ExportFactory<ILedPanel> và tạo bao nhiêu trường hợp như bạn muốn bất cứ khi nào bạn cần đến chúng, do đó, mã của bạn sẽ trông như thế này:

[Import(typeof(ILedPanel)] 
public ExportFactory<ILedPanel> PanelFactory { get; set; } 

public ILedPanel CreateNewLedPanelInstance() 
{ 
    return PanelFactory.CreateExport().Value; 
} 

Phương pháp này cũng đáp ứng bất kỳ nhập khẩu đã tạo ra một phần có. Bạn có thể đọc thêm về cách sử dụng ExportFactory lớp here.

+0

Đó là tuyệt vời, thnx cho việc cập nhật! – TimothyP

Các vấn đề liên quan