我处理结构图错误已经有一段时间了。 错误是:
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/