有你的要求之間存在着矛盾。
首先,你不想因爲安全問題的組成根。其次,您希望依賴由一個容器來解決。但是由於庫不能控制容器,幾乎任何東西都可以注入到代碼中,包括那些試圖從內部破壞任何東西的東西。
一種方法是將您的依賴關係顯式化,以便庫客戶端負責提供您的依賴關係。
namespace Library
{
public class Foo1
{
// a classical IoC dependendency
public Foo1(IBar bar)
{
}
}
}
。另一方面,用合成根是初始化你的庫仍然並不意味着你的庫被污染的明確外點。 CR與本地工廠(也稱爲依賴關係解析器)很好地協作,它負責創建內部對象,並從CR內部進行設置。
namespace Library
{
public interface IFoo { }
// local Foo factory, with a customizable provider
public class FooFactory
{
private static Func<IFoo> _provider;
public static void SetProvider(Func<IFoo> provider)
{
_provider = provider;
}
public IFoo CreateFoo()
{
return _provider();
}
}
// Bar needs Foo
public class Bar
{
public void Something()
{
// you can use the factory here safely
// but the actual provider is configured elsewhere
FooFactory factory = new FooFactory();
IFoo foo = factory.CreateFoo();
}
}
}
,然後在Composition根的地方(靠近應用程序的入口點)
// kernel is set up to map IFoo to an implementation of your choice
public void ComposeRoot(IKernel kernel)
{
FooFactory.SetProvider(() => kernel.Get<IFoo>());
}
正如你所看到的,而不是可能在多個類別提供多個注射點,當地工廠是單注入點,它提供整個庫的完整配置,使其成爲獨立的。
你甚至可以擁有一個不涉及任何IoC容器的提供者,而是創建一個具體的實現,從而使得它容易在沒有任何容器的情況下進行測試。切換到另一個IoC非常簡單,您只需提供另一個提供商。
您的圖書館規模越大,您的課程就具有凝聚力(經常使用彼此),更方便的是擁有本地工廠。你並不需要重新拋出你的類之間的依賴關係(沒有本地工廠,如果你的類A
需求I
和你B
需求A
然後自動B
需求I
),相反,所有的類都依賴於一個單一的工廠。
您的客戶是否會使用Ninject來實現您的實現?如果不是,你打算如何使用Ninject向你的課程注入任何東西? –
我的消費者可能會或可能不會使用Ninject,我不知道。我的類庫可能會作爲NuGet包使用,所以我會在該級別上依賴於Ninject。 –