seesharper / LightInject

An ultra lightweight IoC container
http://www.lightinject.net
MIT License
619 stars 120 forks source link

Two different DBConnection in one scope for WebRequest (MVC). #520

Open Nelo-cool opened 4 years ago

Nelo-cool commented 4 years ago

Hello guys! First of all special thanks to the main developer @seesharper and other contributors. But unfortunately I have a small problem in my code on one of the VMs (Hyper-V) and IIS. Initial Using:

  1. LightInject version="6.2.0"
  2. LightInject.Mvc version="2.0.0"
  3. LightInject.Web version="2.0.0" Target framework: 4.7.2 (try on 4.8 - similarly) Project: ASP.NET MVC 5.2.7 My IoC container:

` public static class IoCConfig { internal static readonly ServiceContainer Container = new ServiceContainer();

    static IoCConfig()
    {
    //Register any services and:
    Container.Register<IServiceContainer>(x => Container, new PerContainerLifetime());
    Container.Register<DBConnection>(new PerScopeLifetime());
    Container.Register<ICommandFactory, CommandFactory>(new PerContainerLifetime());
    Container.Register<ICommandHandler<CreateCommand>, CreateCommandHandler>(new 
        PerScopeLifetime());
    Container.Register<IUrlCreator, UrlCreator>(new PerScopeLifetime());
    }

}`

After i am call RegisterIoC method of IoCConfig class from Global.asax with:

Container.RegisterControllers(); Container.EnableMvc();

And in one of the controllers using Property Injection for inject ICommandFactory and call with CreateCommand:

CommandFactory.Execute(createCommand);

In CreateCommandHandler class using constructor injection DBConnection and IUrlCreator. In implementation UrlCreator class using constructor injection for DBConnection.

Easier to show on the diagram: http://imagecdn.ru/call_tree_for_question.png

And i was hoping to get the same one DBConnection in UrlCreator and CreateCommandHandler because they both PerScope (after i used extensions Web and MVC = ByWebRequest).

But unfortunately I have a two different instances of DBConnection in my logs. After that I noticed that if you add a line in constructor of UrlCreator _logger.Write(Environment.StackTrace); Then the stack is displayed correctly and the instance is the same for both classes! MAGIC! At first I sinned against the asynchrony (async-await) of the MVC controller method, but i try and sync version - the problem didn't go away:(

I checked, scope is the same (GetHashCode), HttpContex too, ThreadId (Thread.ManagedThreadId) too! But DbConnection - two different instances.

Maybe, you will help me guys? Please:)

Nelo-cool commented 4 years ago

New magic: If I use a container.GetInstanse<IEnumerable<ICommandHandler>>(), then everything is fine for a few hours, but then the error returns. Very strange:(

seesharper commented 4 years ago

Could you try with the latest version of LightInject. We did fix a bug related to scopes just recently