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

时间:2011-10-02 16:11:15

标签: multithreading structuremap

我正在处理结构图错误很长一段时间。 错误是:

  

StructureMap.StructureMapException: StructureMap异常代码:202   没有为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()时,它表示它有它。

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

1 个答案:

答案 0 :(得分:3)

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

因此,对于提醒,当应用程序启动时,对于每个配置文件,我将其设置添加到唯一的一个Container:

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例外:)