Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.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# LightInjectIOC容器在解析类型时引发stackoverflow_C#_Inversion Of Control_Ioc Container_Service Locator_Light Inject - Fatal编程技术网

C# LightInjectIOC容器在解析类型时引发stackoverflow

C# LightInjectIOC容器在解析类型时引发stackoverflow,c#,inversion-of-control,ioc-container,service-locator,light-inject,C#,Inversion Of Control,Ioc Container,Service Locator,Light Inject,尝试LightInjectIOC容器时,在解析类型服务时引发stackoverflow异常: 所有类型都已在App_Start中注册: container.RegisterAssembly("MyApp*.dll"); 然后,当我尝试在控制器中解决它时,它失败并引发stackoverflow异常: public SomeController(ISomeService someService) { _someService = someService;

尝试LightInjectIOC容器时,在解析类型服务时引发stackoverflow异常:

所有类型都已在App_Start中注册:

container.RegisterAssembly("MyApp*.dll");
然后,当我尝试在控制器中解决它时,它失败并引发stackoverflow异常:

    public SomeController(ISomeService someService)
    {
         _someService = someService;
    }
使用ServiceLocator时也会出现相同的错误:

ServiceLocator.Current.GetInstance<ISomeService>();
调用GetDefaultDelegate后,执行路径再次返回GetInstance,导致无限循环和堆栈溢出

编辑2-我们进一步跟踪了这一点,它似乎是由同时具有构造函数和属性注入的某个服务引起的:

public class SomeService : ISomeService 
{
    public IAnotherService AnotherService { get; set; }
    public SomeService(IAnotherService anotherService)
    {
        AnotherService = anotherService;
    }
}
正在通过构造函数和属性注入依赖项IAnotherService和AnotherService,但无意使用属性注入器

编辑3

应用程序中有几个层都使用ServiceLocator,因此我最初使用NuGet将LI添加到其自己的项目中,因此我有:

MyApp.IoC.LightInject
MyApp.Repositories
MyApp.Services
MyApp.Web.UI
但实际上没有必要将其添加到自己的项目中,因为可以在UI层中设置服务定位器提供程序:

var serviceLocator = new LightInjectServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => serviceLocator);
因此,我刚刚删除了额外的项目,并将NuGet包放在UI层中。我还安装了LightInject.Annotation,并故意不调用container.EnableAnnotatedPropertyInjection()方法,以确保只使用构造函数注入。它仍在抛出堆栈溢出

要测试解析是否有效,我只是在HomeController.Index()方法中执行此操作:

当我注释掉服务的构造函数时,解析工作和所有依赖项都是通过属性注入来解析的。如果包含构造函数,则会引发stackoverflow异常


尽管解析ISomeService仅在使用属性时有效,但如果该服务的依赖项中包含ISomeService,则无法解析IAnotherService。我希望上面的日志能对这个问题有所帮助。到目前为止,LightInject的性能明显优于Unity

作为LightInject的作者,我将尽我所能回答最好的问题

首先,LightInject不应该抛出StackOverflowException,因此这是需要根据您在这里描述的内容进行研究的

我清楚地理解,在这里,属性注入不是您的意图,因为将服务注入两次(构造函数和属性)没有什么意义

实际上,我们可以做一些事情来避免将依赖项注入到属性中

  • 通过删除公共setter使属性为只读
  • 使用文档中提到的“显式”服务注册来注册服务

    container.Register<ISomeService>(f => new SomeService(f.GetInstance<IAnotherService>())); 
    
  • 如前所述,我将进一步调查StackOverflowException,并对该案例进行适当调整。我的第一个想法是,如果容器发现一个既可以作为构造函数依赖项又可以作为属性依赖项注入的依赖项,则抛出一个异常

    container.Register<IBar, Bar>();
    container.Register<IFoo, FooWithConstructorAndPropertyDependency>();
    
    container.GetInstance<IFoo>();
    
    希望这有帮助

    致意

    伯恩哈德·里希特

    编辑

    虽然这个问题对于您的案例来说似乎已经解决了,但我仍然希望能够在测试中重现这一点。获得异常的原因可能不像同时具有同一类型的构造函数依赖项和属性依赖项的服务那么简单

    以这项服务为例

    public class FooWithConstructorAndPropertyDependency : IFoo
    {
        public FooWithConstructorAndPropertyDependency(IBar bar)
        {
            Bar = bar;
        }
    
        public IBar Bar { get; set; }
    }
    
    LightInject将愉快地注入依赖项

    container.Register<IBar, Bar>();
    container.Register<IFoo, FooWithConstructorAndPropertyDependency>();
    
    container.GetInstance<IFoo>();
    
    container.Register();
    container.Register();
    container.GetInstance();
    

    因此,一定是其他原因导致了异常。如果你能提出一个最小的例子来重现这个异常,我将不胜感激。对我来说,在没有失败的情况下做进一步的调查有点困难:)如果你选择这样做,你可以把它贴在这里或发邮件给我。richter@gmail.com.

    遗憾的是,问题已更新为进一步的详细信息。注释没有帮助。抱歉,更正我上面的编辑。我现在正在调用
    container.EnableAnnotatedPropertyInjection()
    ,它正在使用构造函数注入解析服务。谢谢:)我将重新运行测试,看看是否可以解决所有服务/控制器
    container.EnableAnnotatedPropertyInjection(); 
    
    public class FooWithConstructorAndPropertyDependency : IFoo
    {
        public FooWithConstructorAndPropertyDependency(IBar bar)
        {
            Bar = bar;
        }
    
        public IBar Bar { get; set; }
    }
    
    container.Register<IBar, Bar>();
    container.Register<IFoo, FooWithConstructorAndPropertyDependency>();
    
    container.GetInstance<IFoo>();