2013-05-24 21 views
7

Bạn có thể tăng cường hệ thống mô-đun Prism từ bên trong dịch vụ WCF không? Bởi vì không có vấn đề gì tôi làm phụ thuộc MEF của tôi không được hoàn thành.Hệ thống mô-đun lăng kính từ bên trong dịch vụ WCF?

Ví dụ:

Đây là dịch vụ WCF tôi thực hiện

public class MyService : IMyServiceContract{ 
    // This should get filled by MEF after Prism loads the required modules 
    [Import] 
    IDatabase db; 

    public MyService(){ 
     var bootsrapper = new MyServiceBoostrapper(); 
     bootsrapper.Run(); 
    } 
} 

Đây là Prism tôi boostrapper với hương vị MEF:

public class MyServiceBoostrapper : MefBootstrapper 
{ 
    protected override void ConfigureContainer() 
    { 
     base.ConfigureContainer(); 
    } 

    protected override IModuleCatalog CreateModuleCatalog() 
    { 
     return new ConfigurationModuleCatalog(); 
    } 
    protected override void ConfigureAggregateCatalog() 
    { 
     base.ConfigureAggregateCatalog(); 

     // TODO: Add this assembly ... don't know why 
     this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(MyServiceBoostrapper).Assembly)); 
     this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(IDatabase).Assembly)); 
     // This is what provides the service 
     this.AggregateCatalog.Catalogs.Add(new AssemblyCatalog(typeof(DatabaseImpl).Assembly)); 
    } 

    protected override DependencyObject CreateShell() 
    { 
     // we don't need the shell 
     return null; 
    } 

} 

Đây là mô-đun của tôi rằng chứa giao diện cho cơ sở dữ liệu Prism dịch vụ:

[ModuleExport(typeof(IDatabase))] 
public class ModuleActivator : IModule 
{ 
    public void Initialize() 
    { 
     // Do nothing as this module simply provides the API. 
    } 
} 
public interface IDatabase 
{ 
    // interface methods here ... 
} 

và cuối cùng ở đây là Prism dịch vụ cơ sở dữ liệu bản thân:

[ModuleExport(typeof(DatabaseImpl), DependsOnModuleNames = new string[] { "IDatabase" })] 
public class ModuleActivator : IModule 
{ 
    public void Initialize() 
    { 
     // Do nothing as this is a library module. 
    } 
} 

[Export(typeof(IDatabase))] 
public class DatabaseImpl : IDatabase 
{ 
    /// implementation here ... 
} 

Cố gắng này trong vài giờ cuối cùng không thành công. Nhập db của tôi luôn là null và không bao giờ được khởi tạo.

Lưu ý rằng mọi thứ hoạt động nếu tôi làm tất cả những điều này không có Prism, nhưng chỉ với MEF.

+0

Vậy còn tiến trình về vấn đề này thì sao? –

+0

Tôi nghĩ rằng tôi đã tìm thấy một giải pháp trong cuốn sách "Dependency Injection in .NET" (Phần 3, Ch. 7.3). Vẫn thử nghiệm nó ra. Về cơ bản nó chỉ là một vấn đề hooking vào thói quen khởi động WCF. – drozzy

+0

Như tôi đã nói trong bình luận của tôi. Tôi thực sự nghĩ rằng vấn đề của nó là Định cấu hình vùng chứa của bạn và xem lại các loại ... –

Trả lời

0

Vâng, nó có vẻ như là giải pháp không phải là để sử dụng Prism ở tất cả , vì nó không thêm bất cứ điều gì "mô-đun" với các mô-đun của nó. Có vẻ như các mô-đun là các khái niệm hoàn toàn cho các ứng dụng trực quan.

Thay vào đó, người ta phải móc vào quy trình "khởi động" WCF và đẩy mạnh vùng chứa MEF từ đó. Câu trả lời về làm thế nào để làm điều này là khá tham gia (mặc dù không phức tạp), như WCF đã có nhiều điểm mở rộng/hook-in.

Câu trả lời tôi sử dụng nằm trong cuốn sách Tiêm phụ thuộc trong .NET bởi Mark Seemann trong Chương 7.3: "Soạn các ứng dụng WCF".

Ngắn sao chép toàn bộ chương từ cuốn sách đó vào câu trả lời này, tôi e rằng đó là điều tốt nhất tôi có thể làm.

1

Tôi không chắc chắn rằng các đoạn mã sau sẽ giúp bạn. Tôi chỉ có kinh nghiệm với PRISM và Unity. Chỉ cần thử nó và cho tôi biết những gì đang xảy ra.

protected override void ConfigureContainer() 
    { 
     base.ConfigureContainer(); 

     this.RegisterTypeIfMissing(typeof(IDatabase), typeof(DatabaseImpl), true); 
    } 

Bạn cũng đang tạo và trống ModuleCatalog và không bao giờ định cấu hình nó.

protected override void ConfigureModuleCatalog() 
     { 

      base.ConfigureModuleCatalog(); 

      var moduleCatalog = (ModuleCatalog)ModuleCatalog; 

      Type Initial = typeof(ModuleActivator); 
      moduleCatalog.AddModule(new ModuleInfo 
      { 
       ModuleName = Initial.Name, 
       ModuleType = Initial.AssemblyQualifiedName 
      }); 
     } 
3

Bạn sẽ không có bất cứ điều gì nhập khẩu vào lĩnh vực db của bạn bởi vì đối tượng MyService không được tạo ra bởi các container - nó không thể được tạo ra bởi vì các container được thực sự được tạo ra trong bootstrapper, đó là trong hàm xây dựng của MyService.

Một cách đơn giản để giải quyết vấn đề này là thỏa mãn việc nhập khẩu đối tượng của bạn sau khi vùng chứa được khởi tạo. Để làm như vậy, bạn có thể tiếp xúc với các thùng chứa trong bootstrapper như vậy:

public class MyServiceBoostrapper 
{ 
    public CompositionContainer MyServiceContainer 
    { 
     get { return Container; } 
    } 

    // Rest of bootstrapper definitions... 
} 

Sau đó sửa đổi MyService 's constructor:

public MyService() 
{ 
    var bootsrapper = new MyServiceBoostrapper(); 
    bootsrapper.Run(); 

    // This is an extension method. You'll need to add 
    // System.ComponentModel.Composition to your using statements. 
    bootstrapper.MyServiceContainer.SatisfyImportsOnce(this); 

    // At this stage, "db" should not be null. 
} 
+0

Yea hoạt động. Cảm ơn. Tất nhiên, tôi không cần Prism. Nó chỉ là khó hiểu vấn đề. Ngoài ra, đọc sách 'Dependency Injection in .NET' đã giúp làm sáng tỏ những gì đã được thực hiện ở đâu. Đặc biệt là ví dụ về cách khởi động WCF. Hôm nay tôi quá mệt mỏi để viết câu trả lời ở đây, nhưng đó sẽ là cách chính xác để khởi động một dịch vụ WCF. – drozzy

+0

Vâng, Prism có lẽ không cần thiết ở đây, nhưng tôi đã giải thích lý do tại sao mọi thứ không hoạt động sẽ giúp bạn đưa ra quyết định tốt hơn về cách khởi động dịch vụ của bạn đồng thời cho phép bạn duy trì việc triển khai hiện tại. Dù sao, hy vọng câu trả lời của tôi là một số trợ giúp. –

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