【问题标题】:Why is this instance initiated by Unity not a singleton?为什么Unity发起的这个实例不是单例?
【发布时间】:2009-12-17 15:39:43
【问题描述】:

在我的 asp.net-mvc 应用程序中,我有一个调用静态 CreateContainer() 方法的 statis MvcApplication。

在这种方法中,我创建了我的统一 ioc 容器:

private static IUnityContainer CreateContainer()
{
    var container = new UnityContainer();
    container.RegisterType<IConfigurationService, ConfigFile>();
    container.RegisterType<ILoggerService, NlogLoggerService>();

    container.RegisterInstance<ISearchService>(
        new LuceneSearchService(
            container.Resolve<IConfigurationService>(),
            container.Resolve<ILoggerService>()),
            new ContainerControlledLifetimeManager());
}

如果我很好地理解了我的来源,这应该会给我一个单例 LuceneSearchService 实例。 然而,在我的日志记录中,我可以看到每次请求此实例时我的构造函数都会被命中。

我做错了什么?

【问题讨论】:

    标签: c# unity-container object-lifetime


    【解决方案1】:

    对于单例,您应该将容器的定义移到函数之外,并将其设为静态。默认设置为null。

    然后在您的 CreateContainer 函数中,检查容器是否为空。如果是,则创建并初始化它。否则,直接退货。

    private static IUnityContainer container = null;
    private static IUnityContainer CreateContainer()
    {
        if( container == null )
        {
            container = new UnityContainer();
            container.RegisterType<IConfigurationService, ConfigFile>();
            container.RegisterType<ILoggerService, NlogLoggerService>();
    
            container.RegisterInstance<ISearchService>(
                new LuceneSearchService(
                    container.Resolve<IConfigurationService>(),
                    container.Resolve<ILoggerService>()),
                    new ContainerControlledLifetimeManager());
        }
    
        return container;
    }
    

    【讨论】:

    • P.S.只是我,还是 'var' 现在是 c# 中最被滥用、滥用和误解的关键字?
    • +1。请注意,它说的是“ContainerControlledLifetimeManager”,而不是“Singleton”。由于 OP 每次都在创建一个新容器,因此生命周期非常短。另请注意,UnityContainer 是 IDisposable。
    • 我不使用 ASP.Net MVC 或 Unity(如果那与 MVC 不同?)。我只知道如何做单例:-P
    • 感谢您的回答。你能解释一下为什么我不应该使用 var 吗?据我所知,这与完整编写类型基本相同,只是现在我的编译器将在编译时填补空白,并且我的代码变得不那么混乱。还是有什么我忘记了?
    • 这可能只是个人喜好,但我相信使用 var 会损害可读性。如果您只是将变量声明为 var,那么另一个人来阅读您的代码将不得不浪费时间阅读您的代码,只是为了找出它是什么类型。有时可以使用(主要用于 LINQ 查询)。同样,这只是个人喜好(并且是从与许多人合作的项目中学到的),绝不是侮辱...... :)
    【解决方案2】:

    我认为这可行,假设您直接解析 ISearchService 而不是 LuceneSearchService - 在这种情况下,我认为 Unity 每次都会创建一个新实例,因为不会有现有映射。

    就个人而言,我还将其注册为: container.RegisterType&lt;ISearchService, LuceneSearchService&gt;(new ContainerControlledLifetimeManager());

    【讨论】:

    • 我所有的构造函数都接受一个 ISearchService。没有提到 LuceneSearchService,但日志并没有弥补......
    • 感谢您为我实例化我的单例类型指明了正确的方向。连同这个问题的答案,我得到了我需要的东西
    猜你喜欢
    • 2018-11-07
    • 1970-01-01
    • 1970-01-01
    • 2017-11-25
    • 2013-03-16
    • 1970-01-01
    • 2022-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多