2014-02-11 40 views
2

我正在研究一個小型類庫並使用簡單注射器作爲我的DI。 類庫有一個接入點(我猜想某種服務),它是public,它有一些internal服務和存儲庫。簡單的注射器和內部構造函數

我看到Simple Injector不支持帶內部構造函數的構造函數注入。 例如,我的產品服務是這樣的:

 internal class ProductService : IProductService 
     { 
     private IProductRepository _productRepository; 

     internal ProductService(IProductRepository repository) 
     { 
      if (repository == null) throw new ArgumentNullException("repository"); 

      _productRepository = repository; 
     } 

     } 

而且我的設置:

container.Register<IProductService, ProductService>(); 
container.Register<IProductRepository>(() => new ProductRepository()); 

當我運行代碼,我得到以下異常:

For the container to be able to create ProductService, it should contain exactly one public constructor, but it has 0. 

我的問題:

1)是否有一個特定的原因,注入內部類不起作用建築/設計術語?

2)這種行爲(使用依賴注入與不應該公開的類)是如何實現的並且是它的期望?

+0

的原因是什麼這些類是內部的,而不是公衆:

public class InternalConstructorResolutionBehavior : IConstructorResolutionBehavior { private IConstructorResolutionBehavior original; public InternalConstructorResolutionBehavior(Container container) { this.original = container.Options.ConstructorResolutionBehavior; } public ConstructorInfo GetConstructor(Type serviceType, Type implementationType) { if (!implementationType.GetConstructors().Any()) { var internalCtors = implementationType.GetConstructors( BindingFlags.Instance | BindingFlags.NonPublic) .Where(c => !c.IsPrivate) .ToArray(); if (internalCtors.Length == 1) return internalCtors.First(); } return this.original.GetConstructor(serviceType, implementationType); } } 

這個自定義構造函數解析行爲可以如下注冊? – Steven

回答

3

簡單的噴油器試圖給你一個合理的默認值。默認情況下,它僅限於使用單個公共構造函數的自動佈線類型,因爲有multiple constructors is an anti-pattern。 Simple Injector默認只注入公共構造函數,因爲對於Simple Injector來說,能夠安全地調用一個類型的構造函數,這必須是公共的。例如,當應用程序在(部分信任)沙箱中運行時,簡單注入器將無法調用內部構造函數,儘管可以完全信任地調用內部構造函數,但創建此類型會更慢。爲了性能,最好將類型和構造函數公開。

除了這些技術限制,在正常情況下,組件及其構造函數將公開,因爲通常情況下,您通常會有需要訪問該組件的外部使用者。這些消費者的例子是你的單元測試項目和你的composition root project

因此,合理的默認值是'一個公共構造函數',但類型本身不必是公共的,儘管解析內部類型會更慢,並且可能無法在沙箱中始終工作。換句話說,當你沒有在沙箱中運行時(比如Silverlight或者Windows Phone),Simple Injector將能夠解析內部類型,只要它們有一個公共構造函數。

但是,如果您確實需要或希望您的構造函數爲內部構造函數解析行爲,則可以通過實施和註冊自定義的IConstructorResolutionBehavior來覆蓋構造函數解析行爲。這裏有一個例子:

var container = new Container(); 

container.Options.ConstructorResolutionBehavior = 
    InternalConstructorResolutionBehavior(container); 

// Normal registrations here 
+1

非常好,謝謝你的解釋!我將公開我的構造函數(並同時保留一些內部類)。 – sTodorov