ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CodeGo.net>为DI容器创建线程安全的单例包装

2019-12-02 01:09:07  阅读:247  来源: 互联网

标签:multithreading ninject wpf c net-4-0


我为Ninject DI容器创建了一个包装,打算在WPF应用程序中使用.我希望它是线程安全的,以防我需要在单独的线程中打开新窗口,但是对于使用volatile关键字和锁定我感到困惑.就我所知,锁定非常容易理解,但是我并不是在使用volatile关键字.从我的谷歌搜索结果中,我了解到volatile关键字可确保在多线程环境中对指定实例进行安全的读取访问,但在更改指定实例所占用的内存空间时不会提供任何安全性.我将解决方案与一些线程安全的单例模式示例结合在一起,并提出了此包装器,该包装器将用作服务定位器:

public class NinjectResolver
{
    private static object syncRoot = new object();
    private static volatile NinjectResolver instance = null;
    private static volatile IKernel kernel = null;

    public static NinjectResolver GetInstance()
    {
        lock (syncRoot)
        {
            if (instance == null)
                instance = new NinjectResolver();
        }
        return instance;
    }

    static NinjectResolver()
    {
        lock (syncRoot)
        {
            if (kernel == null)
                kernel = new StandardKernel();
        }
    }

    public void AddBindings(Dictionary<Type, Type> bindings)
    {
        lock (syncRoot)
        {
            foreach (var binding in bindings)
            {
                Type IType = binding.Key;
                Type ImplementationType = binding.Value;
                kernel.Bind(IType).To(ImplementationType);
            }
        }
    }

    private NinjectResolver()
    {
    }

    /// <summary>
    /// Resolves All dependencies for requested instance and returns that instance
    /// </summary>
    /// <typeparam name="T">Requested Implementation type</typeparam>
    /// <returns>Instance of Implementation type</returns>
    public T Resolve<T>()
    {
        return kernel.TryGet<T>();
    }

    /// <summary>
    /// Resolves property injection dependencies in already instantiated Implementation types
    /// </summary>
    /// <param name="obj">Specified instance of implementation type</param>
    public void Inject(object obj)
    {
        kernel.Inject(obj);
    }
}

我的问题是:由于初始化将在App.xaml.cs(首先调用GetInstance())内进行,我是否需要在指定的位置使用锁定,并且这些静态字段是否需要声明为volatile或我可以省略该部分?因为在此结构中它们或多或少是只读的.如果有人能对此有所了解,我将不胜感激.

解决方法:

要实现线程安全的单例模式,您基本上有两个选择:

1.双重检查锁定

public static NinjectResolver GetInstance()
{   
    if(instance == null)
    {
        lock (syncRoot)
        {
            if (instance == null)
                instance = new NinjectResolver();
        }
    }
    return instance;
}

2.在声明时初始化实例

private static volatile NinjectResolver instance = new NinjectResolver();

public static NinjectResolver GetInstance()
{
    return instance;
}

您也可以将代码放入静态块中,然后使用:

private static volatile IKernel kernel = new StandardKernel();

标签:multithreading,ninject,wpf,c,net-4-0
来源: https://codeday.me/bug/20191201/2084599.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有