2011-05-25 78 views

回答

0

我建議的是在系統中定義第一個可擴展性點,在什麼層或什麼組件允許第三方開發人員擴展或完全替代。您必須定義可擴展性的起點和結束位置。

這是在開始開發之前必須要做的設計決策。你稍後可能會改變,但它會消耗更多的時間,你將不得不做很多改變。在你定義這個之後,一切都變得容易多了。

嘗試定義契約(接口),因爲MEF中的契約取代了典型應用程序的緊密耦合。 MEF使用合同在運行時匹配導入和導出組件。

如果您有一個ex。有一些方法ProductRepository,然後創建一個包含這些方法的接口IProductRepository,然後標記ProductRepository與出口屬性是這樣的:

public interface IProductRepository 
{ 
    IEnumerable<Product> GetProducts(Expression<Func<Product, bool>> query); 
} 

[Export(typeof(IProductRepository))] 
public class ProductRepository : IProductRepository 
{ 
    public IEnumerable<Product> GetProducts(Expression<Func<Product, bool>> query) 
    { 
     throw new NotImplementedException(); 
    } 
} 

對於參數的緣故,讓我們說,你有一個服務於同類產品:

public interface IProductService 
{ 
    IEnumerable<Product> GetLatestProducts(int items); 
} 

[Export(typeof(IProductService))] 
public class ProductService : IProductService 
{ 
    private IProductRepository _repository; 


    [ImportingConstructor] 
    public ProductService(IProductRepository repository) 
    { 
     this._repository = repository; 
    } 

    public IEnumerable<Product> GetLatestProducts(int items) 
    { 
     return _repository.GetProducts(p => p.DateCreated == DateTime.Today).OrderByDescending(p => p.DateCreated).Take(items); 
    } 
} 

通過使用Export屬性標記存儲庫,可以使服務通過MEF導入同一個存儲庫。如您所見,我們將工作委託給MEF CompositionContainer以向ProductService提供ProductRepository的實例...我們通過使用依賴注入通過構造器注入來注入此實例。

然後在你的MVC控制器應用同樣的原理,但現在你導入ProductService而不是ProductRepository ......是這樣的:

[Export(typeof(IController))] 
[ExportMetadata("Name","Product")] 
public class ProductController : Controller 
{ 
    private IProductService _service; 

    [ImportingConstructor] 
    public ProductController(IProductService service) 
    { 
     _service = service; 
    } 

    public ActionResult LatestProducts() 
    { 
     var model = _service.GetLatestProducts(3); 
     return View(model); 
    } 
} 

通過導出你的控制器,你可以把你的控制器,每當你想,在相同的組件或獨立的組件中。正如你所看到的,我已經爲控制器添加了另一個屬性[ExportMetadata(「Name」,「Product」)]。這用於在查詢時決定哪個控制器離開組合容器。

接下來你需要做的是從一些目錄:TypeCalog,DirectoryCatalog,AssemblyCatalog或AggregateCatalog創建matchmaker =>組合容器。您告訴目錄加載程序集的位置。你可以在codeplex

現在你需要一種方式來讓你的控制器脫離CompositionContainer。您可以在MVC中執行此操作的地方是ControllerFactory。您必須創建一個自定義ControllerFactory(通過繼承DefaultControllerFactory或實現IControllerFactory接口)。然後在控制器工廠內查詢組合容器,並找到請求的控制器。

正如您大概可以理解的那樣,組合過程從控制器工廠開始:ProductController導入ProductService和ProductService導入ProductRepository。 MEF組合容器遍歷依賴關係圖並滿足這些導入。

+0

謝謝你的答案。你有可以分享的示例應用程序嗎?在此先感謝 – ticklewow 2011-05-26 22:18:12

+0

訂閱此博客,在即將到來的日子裏我打算髮布類似的東西 - http://phalanx.spartansoft.org/author/m-shaqiri – 2011-05-27 00:21:23