StructureMap:多线程环境.没有为PluginFamily定义默认实例 [英] StructureMap: Multithreaded env. No default instance defined for PluginFamily

查看:92
本文介绍了StructureMap:多线程环境.没有为PluginFamily定义默认实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理一段时间的structuremap错误. 错误是:

I'm dealing with structuremap error for quite a while. The error is:

StructureMap.StructureMapException: StructureMap异常代码:202 没有为PluginFamily定义默认实例 SomeNamespace.ISomeInterface,SomeNamespace,Version = 1.0.0.0, 文化=中性,PublicKeyToken =空

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.

Our project is fully multithreaded and StructureMap can be called several times per second with different profile name each time.

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

StructureMap setting is done when application starts. I use the 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是:

The RegistrationConvention is:

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:

I'm calling StructureMap in code like that:

var container = StructureMap.ObjectFactory.Container;

container.SetDefaultsToProfile(Some profile name);

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

许多线程都调用了此代码,但并非每次都出现此错误,但是却有很多错误. 当打印出WhatDoIHave()时,表明它已经拥有.

This code is called by many threads, and I'm getting this error not all the times, but quite a lot. When printing out WhatDoIHave() it indicates it has it.

如有任何建议/更正,我将非常高兴. 预先感谢.

I'll be glad to have any suggestion/correction. Thanks in advance.

推荐答案

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

It was hard to solve, but finally I got there! The problem was I misused StructureMap: StructureMap, as far as I correctly grasped the intention of using it, is intended to dynamicaly load settings once, when application loads. In our project, we're switching profiles many times per seconds and trying to retrieve an instance based on that profile. We got many exceptions like it doesn't recognize the default instance although WhatDoIHave() showed the opposite. The problem was exactly that - calling the Container from many threads and switching profiles upon each request.

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

So, for a reminder, when application starts, for each profile I added its settings to the only one Container:

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

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

在代码的许多地方,我曾经这样称呼StructureMap:

And in many places in code, I used to call StructureMap like that:

  var container = StructureMap.ObjectFactory.Container;

  container.SetDefaultsToProfile(profileName);

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

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

This code was used parallel and each thread used another profile.

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

So, as a fix I created a Container per profile!

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

var container = new StructureMap.Container(registry);

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

And I stored each container in our code, not on StructureMap as before, so each profile-prone thread is using it's own profiled Container. That's even faster then before because you don't have to switch profiles so much, only once!

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

And no more #$@!@ 202 exception :)

这篇关于StructureMap:多线程环境.没有为PluginFamily定义默认实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆