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

发布于 2024-12-07 12:48:29 字数 4736 浏览 1 评论 0原文

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

StructureMap.StructureMapException:StructureMap 异常代码:202 没有为 PluginFamily 定义默认实例 SomeNamespace.ISomeInterface,SomeNamespace,版本=1.0.0.0, 文化=中性,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() 时,它表明它有它。

我很高兴收到任何建议/更正。 提前致谢。

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

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

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

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));

And Container is:

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;
        }
    }
}

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
}

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>>();

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

安稳善良 2024-12-14 12:48:29

虽然很难解决,但我终于解决了!
问题是我滥用了 StructureMap:
据我正确理解使用 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 异常:)

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));

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);

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!

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文