【问题标题】:IoC container and dll memory managementIoC 容器和 dll 内存管理
【发布时间】:2019-05-28 10:28:21
【问题描述】:

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

我从 Main 方法直接和间接从 IoC 容器访问 Singleton

// 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 应该只实例化一次,并且静态实例应该在应用程序中具有完全相同的内存地址,无论它是从哪里调用的,也不管它是如何构造的(Main 或 IoC容器)

但是,正如控制台输出所说,它不是那样工作的。 SingletonInstance 不应被实例化多次。但他们最终自己拥有了不同的地址。

如果我的浅薄理解对我有用,可执行文件会将 dll 加载到它自己的内存中,并且一旦创建了静态成员,就可以在整个 AppDomain 区域中访问该变量。

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

静态成员

非静态类可以包含静态方法、字段、属性或事件。即使没有创建类的实例,静态成员也可以在类上调用。静态成员总是由类名访问,而不是实例名。 无论创建了多少个类实例,静态成员都只存在一个副本。静态方法和属性不能访问其包含类型中的非静态字段和事件,并且它们不能访问任何对象的实例变量,除非它显式传入方法参数中。

我正在寻找SimpleInjector's 文档中的相关阅读,但没有找到。阅读有关动态链接库及其内存管理的内容并不适合我(无论如何,我将一遍又一遍地阅读它!)

  • 程序如何根据内存管理来处理 dll
  • 如果背后是IoC容器,SimpleInjector通过Container.Register();注册的依赖是如何处理的

以上项目将是我的终极问题。

【问题讨论】:

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


    【解决方案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

    【讨论】:

      猜你喜欢
      • 2010-11-08
      • 2011-05-01
      • 2012-03-19
      • 2012-11-06
      • 2012-02-27
      • 2020-11-02
      • 2011-01-16
      • 1970-01-01
      • 2012-10-11
      相关资源
      最近更新 更多