Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有ninject的循环依赖_C#_Dependency Injection_Inversion Of Control_Ninject - Fatal编程技术网

C# 具有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

我正试图找出正确的方法,用ninject绑定这样的东西

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;
}