multithreading - StructureMap:多线程环境。没有为 PluginFamily 定义默认实例

标签 multithreading structuremap

我处理结构图错误已经有一段时间了。 错误是:

StructureMap.StructureMapException: StructureMap Exception Code: 202 No Default Instance defined for PluginFamily SomeNamespace.ISomeInterface, SomeNamespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

我们的项目是完全多线程的,StructureMap 可以每秒调用多次,每次使用不同的配置文件名称。

StructureMap 设置在应用程序启动时完成。 我使用 StructureMap.Configuration.DSL.Registry:

var registry = new Container(...some parameters settings...);
StructureMap.ObjectFactory.Configure(x => x.IncludeRegistry(registry));

容器是:

class Container : StructureMap.Configuration.DSL.Registry
{
    public Container(...Some settings parameters...)
    {
        For<IConnG>().Use<DG>()
            .Ctor<string>("user").Is(some parameter)
            .Ctor<string>("pass").Is(some parameter)
            .Ctor<string>("site").Is(some parameter)
            .Ctor<string>("DateFormat").Is(some parameter);

        For<IRPG>().Use<RPG>();

        Scan(asm =>
        {
            asm.TheCallingAssembly();
            asm.Include(type => type.IsAbstract == false && type.IsSubclassOf(typeof(BaseC)));
            asm.With(new RegistrationConvention());
        });

        var actionName = (enumA)Enum.Parse(typeof(enumA), some parameter);

        switch (actionName)
        {
            case enumA.ActionA:
                Profile(enumA.ActionA.ToString(), (pe) =>
                {
                    pe.For...;
                    pe.For...;
                    pe.For...;
                    pe.For<IXXX>().Use<DefaultXXX>();
                    **pe.For<IAction<SomeNamespace.SearchParams, SomeNamespace.SearchParams>>().Use<DefaultSearchParams>();**
                    pe.For...;
                });
                break;

            case enumA.ActionB:
                Profile(enumA.ActionB.ToString(), (pe) =>
                {
                    pe.For...;
                    pe.For...;
                    pe.For...;
                    pe.For<IXXX>().Use<DefaultXXX>();
                    **pe.For<IAction<SomeNamespace.SearchParams, SomeNamespace.SearchParams>>().Use<DefaultSearchParams>();**
                    pe.For...;
                });
                break;

            case enumA.ActionC:
                Profile(enumA.ActionC.ToString(), (pe) =>
                {
                   pe.For...;
                    pe.For...;
                    pe.For...;
                    pe.For<IXXX>().Use<DefaultXXX>();
                    **pe.For<IAction<SomeNamespace.SearchParams, SomeNamespace.SearchParams>>().Use<XXXSearchParams>();**
                    pe.For...;
                });
                break;

            case enumA.ActionD:
                Profile(enumA.ActionD.ToString(), (pe) =>
                {
                    pe.For...;
                    pe.For...;
                    pe.For...;
                    pe.For<IXXX>().Use<DefaultXXX>();
                    **pe.For<IAction<SomeNamespace.SearchParams, SomeNamespace.SearchParams>>().Use<DefaultSearchParams>();**
                    pe.For...;
                });
                break;
        }
    }
}

RegistrationConvention 是:

public class RegistrationConvention : StructureMap.Graph.IRegistrationConvention
{
    #region IRegistrationConvention Members

    public void Process(Type type, StructureMap.Configuration.DSL.Registry registry)
    {
        var interfaces = new List<Type>
        {
            type.GetInterface("IInfo`1"),
            type.GetInterface("IBook`1"),
            type.GetInterface("IConf`1"),
            type.GetInterface("IClxP`1"),
            type.GetInterface("ICanc`1"),
            type.GetInterface("IConf2`1"),
            type.GetInterface("IMaxP`1"),
            type.GetInterface("IAction`1")
        };

        interfaces
            .ForEach(contractType =>
                     {
                         if (contractType != null)
                         {
                             registry.For(contractType).Use(type);
                         }
                     });
    }

    #endregion
}

我在这样的代码中调用 StructureMap:

var container = StructureMap.ObjectFactory.Container;

container.SetDefaultsToProfile(Some profile name);

var adaptor = container.GetInstance<IAction<SomeNamespace.SearchParams, SomeNamespace.SearchParams>>();

这段代码被很多线程调用,我不是每次都会遇到这个错误,但确实有很多次。 当打印出 WhatDoIHave() 时,它表明它有它。

我很乐意提出任何建议/更正。 提前致谢。

最佳答案

很难解决,但我终于解决了! 问题是我误用了 StructureMap: 就我正确理解使用它的意图而言,StructureMap 旨在在应用程序加载时动态加载设置一次。 在我们的项目中,我们每秒多次切换配置文件并尝试根据该配置文件检索实例。尽管 WhatDoIHave() 显示相反的情况,但我们遇到了很多异常,例如它无法识别默认实例。 问题恰恰是 - 从多个线程调用容器并根据每个请求切换配置文件。

所以,提醒一下,当应用程序启动时,对于每个配置文件,我将其设置添加到唯一的一个容器中:

var registry = new OurRegistry(settings parameters..., profileName);

StructureMap.ObjectFactory.Configure(x => x.IncludeRegistry(registry));

在代码的很多地方,我曾经这样调用 StructureMap:

  var container = StructureMap.ObjectFactory.Container;

  container.SetDefaultsToProfile(profileName);

  var adaptor = container.GetInstance<ISomeInterface<ConcreteType>>();

此代码并行使用,每个线程使用另一个配置文件。

因此,作为修复,我为每个配置文件创建了一个容器!

var registry = new OurRegistry(settings parameters..., profileName);

var container = new StructureMap.Container(registry);

我将每个容器存储在我们的代码中,而不是像以前那样存储在 StructureMap 中,因此每个易受配置文件影响的线程都在使用它自己的配置文件容器。 这比以前更快,因为您不必多次切换配置文件,只需一次!

不再有#$@!@ 202 异常 :)

关于multithreading - StructureMap:多线程环境。没有为 PluginFamily 定义默认实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7627502/

相关文章:

c# - StructureMap 在 HttpContext 上抛出 ArgumentNullException

c# - 在单独的线程中打开表单,并将其保留在应用程序中其他窗口的顶部

python - 自修复 Python 线程

windows - 了解 MsgWaitForMultipleObjects

c# - 使用结构图注入(inject)多个匹配类

nhibernate - NHibernate 2.1 和 StructureMap 的构造函数依赖注入(inject)

c# - 为什么锁确保底层监视器被释放而直接使用监视器却没有?

java - 使用 Jbutton 停止线程 (Java)

c# - 如何使用结构图获取泛型类的所有实例

structuremap - 拦截方法调用以增加功能的最简单方法是什么?