C# 具有ninject的循环依赖
我正试图找出正确的方法,用ninject绑定这样的东西C# 具有ninject的循环依赖,c#,dependency-injection,inversion-of-control,ninject,C#,Dependency Injection,Inversion Of Control,Ninject,我正试图找出正确的方法,用ninject绑定这样的东西 interface IMainService { void DoStuff(); } interface IOtherService { void DoSomeMagic(); } abstract class BaseClass { //many stuff here } class MainClass : BaseClass, IMainService { public MainClass(IOth
interface IMainService
{
void DoStuff();
}
interface IOtherService
{
void DoSomeMagic();
}
abstract class BaseClass
{
//many stuff here
}
class MainClass : BaseClass, IMainService
{
public MainClass(IOtherService s)
{
}
public void DoStuff()
{
throw new NotImplementedException();
}
//do many other things
}
class OtherClass : IOtherService
{
public OtherClass(IMainService s)
{
}
public void DoSomeMagic()
{
throw new NotImplementedException();
}
}
class BaseModule : NinjectModule
{
public override void Load()
{
Bind<MainClass>().To<MainClass>();
Bind<IMainService>().To<MainClass>();
Bind<IOtherService>().To<OtherClass>();
}
}
static class Program
{
static void Main()
{
var kernel = new StandardKernel(new BaseModule());
var main = kernel.Get<MainClass>();
}
}
我不知道如何编写BaseModule。我只需要一个MainClass实例和一个OtherClass实例(比如Singleton)
我试过这样的方法:
Bind<MainClass>().To<MainClass>().InSingletonScope();
Bind<IMainService>().To<MainClass>().InRequestScope();
Bind<IOtherService>().To<OtherClass>().InSingletonScope();
Bind().To().InSingletonScope();
Bind().To().InRequestScope();
绑定().To().InSingletonScope();
但也有同样的错误
如何为MainClass和IMainService接口编写只使用一个实例的绑定
感谢您的回答。正如错误消息所说,您在
MainClass
和OtherClass
之间有一个循环依赖关系,因为如果没有另一个类的实例,您无法创建一个类。理想情况下,您应该重新构造类层次结构以删除此需求
如果不能,解决方案是对一个(或两个)类使用属性注入,例如
public interface IMainService
{
void DoStuff();
IOtherService OtherService { set; }
}
public class MainClass
{
public IOtherService OtherService { get; set; }
public void DoStuff() { ... }
}
public class OtherService
{
public OtherService(IMainService main)
{
main.OtherService = this;
}
}
我认为你不应该使用属性或setter方法,你最好使用Lazyness。懒散的概念解决了这个问题。问题在于,如果对象之间存在循环依赖关系,那么就不清楚首先创建什么。懒散的解决方法是:一旦对象被真正使用(一般来说,当调用公共方法时,它需要存在)。如果可能,请避免使用属性或设置器。它们使对象可变(不利于线程安全,当依赖项只需注入一次时就不需要) 你们的施工人员应该是这样的:
public OtherService(Lazy<IMainService> main)
{
this.main = main;
}
public MainClass(Lazy<IOtherService> s)
{
this.s = s;
}
public-OtherService(Lazy-main)
{
this.main=main;
}
公共主类(s)
{
这个.s=s;
}
您可以通过调用“ToMethod”(“基于get方法创建惰性方法的lambda方法”),在Ninject模块中使用Load方法描述这些惰性依赖项
这里给出了一个关于lazyness如何使用Ninject解决循环依赖的清晰示例。它还描述了一个帮助器方法(BindLazy)来解决您的问题。
谢谢你的提示。我找到了使用属性注入的完美解决方案。但它没有IMainServices上的IOtherService OtherService{set;},因为我用[Inject]装饰属性时,Ninject向其自身添加正确的实例。这不起作用。对于最新版本的Ninject,如果对两者都使用属性注入,它将抛出一个
StackOverflowException
,如果只有一个使用属性注入(和另一个构造函数注入),它将抛出“检测到循环依赖项”.Ah,但只要您使用的范围不是瞬态范围(默认值),它就可以工作。我使用了这个。这非常好!感谢您指出,可以使用Lazy
;这是一个好主意。特别是对于Ninject,我应该指出,有一些现成的扩展可以为您完成所有注入工作:
public OtherService(Lazy<IMainService> main)
{
this.main = main;
}
public MainClass(Lazy<IOtherService> s)
{
this.s = s;
}