UNITY:如何使用构造函数注入实现线程安全的Container.Resolve()函数?

时间:2012-02-07 16:27:37

标签: c# unity-container constructor-injection

我在我的项目中使用Unity 2.0,我在Parallel.ForEach代码块中同时读取了很多文件:

Parallel.ForEach(files, currentFile =>
{
    using(IMsBuildProjectLoader msBuildProject = Container.Resolve<IMsBuildProjectLoader>(new ParameterOverride("projectFileName", currentFile)))
    {
        // file processing
    }
}

Resolve(新的ParameterOverride(“projectFileName”,currentFile)函数有时会抛出ResolutionFailedException:

ResolutionFailedException: Resolution of the dependency failed, 
type = "Porthus.Build.Common.Interfaces.IMsBuildProjectLoader", name = "(none)". 
Exception occurred while: Calling constructor XXX.Build.Common.Types.MsBuildProjectLoader(System.String projectFileName). 
Exception is: ArgumentException - Item has already been added. Key in dictionary: 'xxx'  Key being added: 'xxx'

这是同时加载同一个文件时 - Resolve函数同时创建两个具有相同参数的IMsBuildProjectLoader实例。它不能通过files.Distinct()过滤器来解决。上面的代码只是一个代码示例来解释我的问题。

问题是:如何实现线程安全的UnityContainer.Resolve函数?是否可以使用一些Unity扩展类来完成它?

IMsBuildProjectLoader

public interface IMsBuildProjectLoader : IDisposable
{
}

MsBuildProjectLoader

public class MsBuildProjectLoader : Project, IMsBuildProjectLoader
{
    public MsBuildProjectLoader(string projectFileName)
        : base()
    {
        // Load the contents of the specified project file.
        Load(projectFileName);
    }
}

MsBuildProjectLoader以这种方式注册:

container.RegisterType<IMsBuildProjectLoader, MsBuildProjectLoader>();

1 个答案:

答案 0 :(得分:0)

Resolve实际上是线程安全的(或者说是微软P&amp; P的那些人)。 可能不是线程安全的是 MsBuildProjectLoader 的实现,或者更具体地说是它的构造函数。 您可能只需使用 new 以相同的异步方式创建MsBuildProjectLoader的新实例,就会遇到同样的问题

您没有包含Load的实现,但根据异常,我会假设它以非线程安全的方式操作共享或静态字典。 如果是这种情况,您应该使该字典线程安全(例如,将其替换为ConcurrentDictionary)。