[英]How can I resolve circular dependencies in Funq IoC?
我有兩個課程,我需要互相參考。
class Foo
{
public Foo(IBar bar) {}
}
class Bar
{
public Bar(IFoo foo) {}
}
當我做:
container.RegisterAutoWiredAs<Foo, IFoo>();
container.RegisterAutoWiredAs<Bar, IBar>();
當我嘗試解決任一接口時,我得到一個循環依賴圖,導致無限循環。 有沒有一種簡單的方法可以在Funq中解決這個問題,或者您知道一種解決方法嗎?
您總是可以(並且在所有容器中,我會說)依賴Lazy作為依賴,這將產生所需的結果。 在Funq:
public Bar(Lazy<IFoo> foo) ...
public Foo(Lazy<IBar> bar) ...
container.Register<IBar>(c => new Bar(c.LazyResolve<IFoo>());
container.Register<IFoo>(c => new Foo(c.LazyResolve<IBar>());
你的問題的答案是否定的,沒有簡單的方法。 鑒於上面的代碼, 沒有 Funq就不可能構造任何一個類,所以沒有理由期望Func能夠做到這一點。
var foo = new Foo(/* what do I pass here? */);
var bar = new Bar(foo);
當然,如果你有一個沒有依賴的IFoo
或IBar
另一個實現,或者你重構,它可能是可能的。
一般來說,“在執行依賴注入時如何分解循環引用”這一問題的答案是:“使用屬性注入”。
class Foo
{
public Foo() {}
// Break the dependency cycle by promoting IBar to a property.
public IBar Bar { get; set; }
}
class Bar
{
public Bar(IFoo foo) {}
}
使用Funq我認為這將是注冊此依賴項的方法。
container.Register<IBar>(c =>
{
var foo = new Foo();
var bar = new Bar(foo);
foo.Bar = bar;
return bar;
});
此外,我同意蒂姆羅傑斯的評論。 當你有一個循環依賴,你的設計可能有一個問題,你應該看看它。 這並不總是錯的,但往往是錯的。 但是,您展示的代碼非常抽象,我們無法就此提供任何反饋。
這對我有用:
using Funq;
using NUnit.Framework;
namespace FunqIoCyclicReferenceTest
{
[TestFixture]
public class FunqIoCCyclicReferenceTest
{
[Test]
public void Please_Work()
{
var container = new Container();
container.Register<IBar>(c => new Bar());
container.Register<IFoo>(c => new Foo(c.Resolve<IBar>()));
var foo = container.Resolve<IFoo>();
Assert.IsNotNull(foo);
}
}
public class Foo : IFoo
{
public Foo(IBar bar)
{
bar.Foo = this;
Bar = bar;
}
public IBar Bar { get; set; }
}
public interface IBar
{
IFoo Foo { get; set; }
}
public interface IFoo
{
IBar Bar { get; set; }
}
public class Bar : IBar
{
public IFoo Foo { get; set; }
}
}
編輯
同樣的想法,但在構造函數中沒有副作用:
// interfaces
public interface IBar
{
IFoo Foo { get; set; }
}
public interface IFoo
{
IBar Bar { get; set; }
}
// implementations
public class Foo : IFoo
{
public IBar Bar { get; set; }
}
public class Bar : IBar
{
public IFoo Foo { get; set; }
}
// usage
container.Register<IBar>(c => new Bar());
container.Register<IFoo>(c =>
{
var bar = c.Resolve<IBar>();
var foo = new Foo();
bar.Foo = foo;
foo.Bar = bar;
});
ps但我同意Tim Rogers的說法 - 循環引用是一個需要解決的問題。
在容器中注冊類型后,使容器可用作靜態變量:
public static class ContainerHolder
{
public static Container Container {get;set;}
}
public class Foo : IFoo
{
private IBar _bar;
public Foo(IBar bar)
{
_bar = bar;
}
}
public class Bar : IBar
{
private IFoo _foo
{
get { return ContainerHolder.Container.Resolve<IFoo>(); }
}
public Bar()
{
}
}
我有一個類似的場景,兩個類之間的依賴關系使我意識到它們實際上應該合並為一個類。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.