我正在处理结构图错误很长一段时间。 错误是:
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()时,它表示它有它。
我很乐意有任何建议/更正。 提前谢谢。
答案 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例外:)