IoC容器和dll内存管理

时间:2019-05-28 10:28:21

标签: c# .net memory-management inversion-of-control simple-injector

我正在处理一个服务器项目,该服务器具有一些不同的独立层和一些单例类。我使用SimpleInjector(一个IoC容器)跨所有层。完整的可执行示例源代码可从https://github.com/DamonJung/TestAdvanture001获得。(不必要冗长,因为我试图在那里重现另一个问题。

我直接从IoC容器间接访问Singleton中的Main方法。

// Use case in Main
.
.
using Impl;    

static void Main(string args[])
{
    .
    .
    // Singleton.Instance address = 0x0301f001 for example.
    var context = Singleton.Instance.GetContext();

    // SimpleInjector
    // Singleton.Instance address inside of the dependency = 0x0408f023 for example.
    var di = Container.GetInstance<ISomeInterface>();
    var contextFromIoC = di.GetContext();
    .
    .
}

我希望Singleton仅应实例化一次,并且静态实例在应用程序中应该具有完全相同的内存地址,无论从何处调用它,以及如何构造(由{{1} }或IoC容器

但是,正如控制台输出所表明的那样,它不是那样工作的。 Main的{​​{1}}不应被多次实例化。但是他们最终自己有了一个不同的地址。

enter image description here

如果我的浅见正确,可执行文件会将dll加载到其自己的内存中,一旦创建了静态成员,就可以在整个Singleton区域中访问该变量。

不是this确认有关静态变量的事实,不是吗?

  

静态成员

     

非静态类可以包含静态方法,字段,属性或事件。即使没有创建该类的实例,该静态成员也可以在该类上调用。始终通过类名称而不是实例名称访问静态成员。 仅存在一个静态成员的副本,无论创建了多少个该类实例。静态方法和属性无法访问其包含类型的非静态字段和事件,除非在方法参数中明确传递了实例变量,否则它们无法访问任何对象的实例变量。

我在搜索Instance文档中的相关内容,但没有找到。对动态链接库及其内存管理的了解并不适合我(反正我会一遍又一遍地阅读它!)

  • 程序在内存管理方面如何处理dll
  • 如果后面是IoC容器,那么AppDomain在通过SimpleInjector's注册依赖项时如何处理依赖项

以上是我的最终问题。

1 个答案:

答案 0 :(得分:1)

因为您的代码创建了两个实例,所以创建了两个实例。

第一个是由以下代码创建的

public class Singleton
{
    public static readonly Singleton Instance = new Singleton();
    // ....
}

,当您将类型注册到SimpleInjector

时,创建第二个

如果只想创建一次实例,则可以使用私有构造函数

public class Singleton
{
    static Singleton()
    {
        Singleton.Instance = new Singleton();
    }
    public static Singleton Instance { get; }

    private Singleton(){ 
    }
}

这样,只有Singleton类会自行创建。

要在SimpleInjector中注册单身人士,可以使用RegisterInstance方法:

container.RegisterInstance<Singleton>(Singleton.Instance);

通过这种方式,更常见的是让容器自己管理实例而不依赖于静态属性,这可能表明您使用的是service locator,这是一种常见的反模式。

如果您想让SimpleInjector管理您应该使用的实例

container.RegisterSingleton<Singleton>();

通过这种方式SimpleInjector只会为容器创建一个Singleton实例。

请参见Singleton lifestyle in the SimpleInjector documentation