如果我有一個類,這對同類型的雙重依賴(需要兩種不同的情況下),如果實例之間唯一的區別是一個更深層次的依賴性,什麼是對的最佳途徑Ninject是否執行DI並將兩個圖分開?Ninject:注射相同類型的兩個不同的對象
實例對象圖:
foo → ClassA → ClassB
bar → ClassA → ClassB
C
的類的構造函數:
public class C
{
public C(ClassB foo, ClassB bar) { … }
}
那麼,如何確保與foo
實例化的ClassB
作爲ClassB
扶養被提供foo
和bar
… bar
?
只是爲了一些背景,我有一些需求的變化,所以我需要一個複合只寫庫
public class CompositeWriteRepository<T> : IAdd<T>
{
public CompositeWriteRepository(IAdd<T> foo, IAdd<T> bar, Func<T, bool> descriminator) { ... }
public Add(T entity)
{
if (descriminator(entity)) {
foo.Add(entity);
} else {
bar.Add(entity);
}
}
}
隨着嘲諷更換隻寫庫(IADD),這是很容易,我可以使用名稱注入:
kernel.Bind<IAdd<EntityType>>().To<fooRepository>().Named("foo");
kernel.Bind<IAdd<EntityType>>().To<barRepository>().Named("bar");
kernel.Bind<IAdd<EntityType>>().To<CompositeWriterRepository<EntityType>>()
.WithConstructorArgument("foo", x => x.Kernel.Get<IAdd<EntityType>>("foo")
.WithConstructorArgument("bar", x => x.Kernel.Get<IAdd<EntityType>>("bar");
問題出在我使用真實存儲庫時; foo
和bar
最終寫入文件,以便它們需要不同的文件名。由於它們是StreamWriter
存儲庫,它們的一個依賴項實際上獲取了兩個不同的文件名。
string FileName → FileStreamWriterFactory → StreamRepository → CompositeRepository
我發現迄今建造的東西,唯一的辦法就是讓一個名爲FileName
,名爲FileStreamWriterFactory
,命名爲StreamRepository
× 2(一次foo
和一次bar
)。這好像很多的工作,所以我希望有更好的解決方案。
,如果需要,我可以重新設計,感覺就像一個優雅的方式來迅速分離該條目時要求更改添加。我意識到我的課都是很具體,但我認爲單一職責一般會支持這一點,在我的情況下,我們寫了一堆的小應用程序,並擁有了更多的要求,我們可以實現這樣的一個好辦法,具有可重複使用的代碼,很多的圍繞這一點,我基本上只需要重新配置不同的任務。
解決方案
Remo Gloor應該得到信用;他可能是最好的做法。
我實際上做的就是創建一個新的擴展
public static bool WhenAnchester(this IRequest request, Func<IRequest, bool> conditions)
{
var parentContext = request.ParentContext;
if (parentContext == null) {
return false;
}
return conditions(parentContext.Request) ||
parentContext.Request.WhenAnchester(conditions);
}
這就讓我輕鬆地控制文件中獲取注入到存儲庫。
kernel.Bind<string>().ToConstant("Foo.txt")
.When(x => x.Target.Name == "filepath" &&
x.WhenAnchester(t => t.Target != null && t.Target.Name == "Dest1"));
kernel.Bind<string>().ToConstant("Bar.txt")
.When(x => x.Target.Name == "filepath" &&
x.WhenAnchester(t => t.Target != null && t.Target.Name == "Dest2"));
有可能是一個更好的解決方案,所以我不會推薦這個給別人,但它的工作對我很好。
DI容器應該解除特定實現的依賴關係,因此這些類只依賴於接口。而你想要的是相反的,我們試圖避免遵循IoC的想法。 – zerkms 2012-02-22 23:08:59
我交換了另一個IAdd的一個實現,我這樣做只是寫一個新類(複合IAdd)並更改我的合成根。誠然,它不是一個非常強烈的指示我正在使用DI,但這似乎不像一個代碼嗅到我。複雜性實際上是因爲我的類不關心,所以我最終得到兩個非常相似的依賴關係圖,而且我的構圖需要關心(應該),因爲業務需求是如此。我可以引入兩種新的區分類型,它可能更清晰,但也更多變化。 – 2012-02-22 23:19:42