目前我已经获得了一个WCF项目,该项目使用Structure map 2.6.1.0进行反转控制。最近我们发现该服务偶尔会出现以下错误消息
Structure map issue
Date time: 2013-11-15 05:19:58
API name: SaveJobSeekerApplicationToFocusTalent
Input data: JobSeekerId: 793576, CustomerJobId: 805299, IsApproved: True, ApprovalRequiredReason: , ApplicationScore: 927
Error response:
Exception source: mscorlib
Exception message: StructureMap Exception Code: 202
No Default Instance defined for PluginFamily Focus.Services.ServiceContracts.ICandidateService, Focus.Services, Version=2.0.6.0, Culture=neutral, PublicKeyToken=null
我们有四项服务
TalentService.svc ReportService.svc MigrationService.svc ImportSerice.svc
以下是TalentService的代码
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class TalentService : InboundServiceBase, ITalentService
{
public TalentService()
{
InitialiseFocus(null, null, null, ConfigurationManager.AppSettings.Get("Focus-ClientTag"));
}
public TalentService(IAuthenticationService authenticationService, ICandidateService candidateService, IProcessorService processorService, string clientTag)
{
_authenticationService = authenticationService;
_candidateService = candidateService;
_integrationClientTag = clientTag;
_processorService = processorService;
}
protected void InitialiseFocus(IAuthenticationService authenticationService, ICandidateService candidateService, IProcessorService processorService, string clientTag)
{
InitialiseBootStrapper();
lock (SyncObject)
{
// Setup the services
if (_authenticationService == null)
_authenticationService = (authenticationService ?? ObjectFactory.GetInstance<IAuthenticationService>());
if (_candidateService == null)
_candidateService = (candidateService ?? ObjectFactory.GetInstance<ICandidateService>());
if (_processorService == null)
_processorService = processorService ?? (_processorService = ObjectFactory.GetInstance<IProcessorService>());
// Set up the client tag
_integrationClientTag = clientTag;
// Start the session with Focus Services
_integrationSession = StartSession();
// Authenticate the Integration User so that we get the Integration UserContext set up
_integrationUserContext = LogIn();
}
}
}
** InboundServiceBase类的代码**
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[ServiceContext]
public abstract class InboundServiceBase : ServiceBase
{
private static bool _bootStrapperInitialized;
private static bool _bootMigrationStrapperInitialized;
protected static readonly object SyncObject = new object();
/// <summary>
/// Initialises the boot strapper.
/// </summary>
protected void InitialiseBootStrapper()
{
if (!_bootStrapperInitialized)
lock (SyncObject)
{
var path = AppDomain.CurrentDomain.BaseDirectory + "StructureMapDump.txt";
ServiceBootStrapper.Initialize(path);
_bootStrapperInitialized = true;
}
}
protected void InitialiseMigrationBootStrapper()
{
if (!_bootMigrationStrapperInitialized)
lock (SyncObject)
{
var path = AppDomain.CurrentDomain.BaseDirectory + "StructureMapDump.txt";
MigrationServices.ServiceBootStrapper.Initialize(path);
_bootMigrationStrapperInitialized = true;
}
}
}
实际启动过滤器的代码
public class ServiceBootStrapper
{
/// <summary>
/// Initializes the Services.
/// </summary>
/// <param name="dumpPath">The dump path.</param>
public static void Initialize(string dumpPath)
{
// Initialise Structure Map
ObjectFactory.Initialize(x =>
{
x.AddRegistry(new PerRequestContextRegistry<FocusUnitOfWork>("Focus"));
x.AddRegistry(new PerRequestContextRegistry<FocusExplorerUnitOfWork>("FocusExplorer"));
x.AddRegistry(new PerRequestContextRegistry<FocusReportingUnitOfWork>("FocusReporting"));
x.AddRegistry(new PerRequestContextRegistry<FocusCareerUnitOfWork>("FocusCareer"));
x.AddRegistry(new ServiceRegistry());
});
// Dump what we have added to Structure Map
try
{
var whatDoIHave = ObjectFactory.WhatDoIHave();
File.WriteAllText(dumpPath, whatDoIHave);
}
catch { }
var coreService = ObjectFactory.GetInstance<CoreService>();
var appSettings = coreService.AppSettings;
// Initialise the Logger
// Read and assign application wide logging severity
Logger.Severity = appSettings.LogSeverity;
// Send log / profile events to a database.
var application = appSettings.Application;
var errorEmailTo = appSettings.OnErrorEmail;
var logToDatabase = new LogToDatabase(application, "FocusLog");
// Attach LogToEmail first so we get an email if the Db is down!
// If LogToDatabase is first the event handler will bomb out if the
// Logging / Profiling Db can't be found so LogToEmail is first
if (errorEmailTo.IsNotNullOrEmpty()) Logger.Instance.Attach(new LogToEmail(application, errorEmailTo));
Logger.Instance.Attach(logToDatabase);
// Initialise the Profiler
if (appSettings.ProfilingEnabled)
Profiler.Instance.Attach(logToDatabase);
// Initialise the Cacher
Cacher.Initialize(new CacheToHttpRuntime(appSettings.CachePrefix));
// Initialise the Emailer
if (appSettings.EmailsEnabled)
Emailer.Instance.Attach(new EmailToSmtp());
else
Emailer.Instance.Attach(new EmailToFile());
}
#region Service Registry
private class ServiceRegistry : Registry
{
/// <summary>
/// A structure map registry for creating a Services.
/// </summary>
public ServiceRegistry()
{
// Repositories
For<IFocusRepository>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new FocusRepository(ObjectFactory.GetInstance<UnitOfWorkScopeBase<FocusUnitOfWork>>().Current));
For<IFocusExplorerRepository>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new FocusExplorerRepository(ObjectFactory.GetInstance<UnitOfWorkScopeBase<FocusExplorerUnitOfWork>>().Current));
For<IFocusReportingRepository>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new FocusReportingRepository(ObjectFactory.GetInstance<UnitOfWorkScopeBase<FocusReportingUnitOfWork>>().Current));
For<IFocusCareerClientRepository>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new FocusCareerClientRepository(ObjectFactory.GetInstance<UnitOfWorkScopeBase<FocusCareerUnitOfWork>>().Current));
// Focus Services
For<CoreService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new CoreService());
For<ICoreService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new CoreService());
For<IAuthenticationService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new AuthenticationService());
For<IAccountService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new AccountService());
For<IJobService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new JobService());
For<ISearchService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new SearchService());
For<ICandidateService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new CandidateService());
For<IEmployerService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new EmployerService());
For<IEmployeeService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new EmployeeService());
For<IProfileService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new ProfileService());
For<IReportService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new ReportService());
For<IStaffService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new StaffService());
For<IExplorerService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new ExplorerService());
For<IProcessorService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new ProcessorService());
For<IReportingService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new ReportingService());
For<IProcessIssueService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new ProcessIssueService());
For<CareerServices.ServiceContracts.IAccountService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new CareerServices.ServiceImplementations.AccountService());
For<CareerServices.ServiceContracts.IUtilityService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new CareerServices.ServiceImplementations.UtilityService());
For<CareerServices.ServiceContracts.IResumeService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new CareerServices.ServiceImplementations.ResumeService());
For<CareerServices.ServiceContracts.IOccupationService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new CareerServices.ServiceImplementations.OccupationService());
For<CareerServices.ServiceContracts.ISearchService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new CareerServices.ServiceImplementations.SearchService());
For<CareerServices.ServiceContracts.IAnnotationService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new CareerServices.ServiceImplementations.AnnotationService());
For<CareerServices.ServiceContracts.IPostingService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new CareerServices.ServiceImplementations.PostingService());
For<CareerServices.ServiceContracts.IAccountOrganizerService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new CareerServices.ServiceImplementations.AccountOrganizerService());
For<CareerServices.ServiceContracts.IIssueService>().LifecycleIs(Lifecycles.GetLifecycle(InstanceScope.PerRequest)).Use(x => new CareerServices.ServiceImplementations.IssueService());
}
}
#endregion
}
如果客户端是单线程的,当多线程客户端访问调用不同服务的服务然后我得到结构图问题时,上面的代码工作正常。我相信这是因为广泛使用GetInstance方法我不确定它是否是线程安全的所以我把syncObject同步到对象实例化进程但看起来它没有帮助
请告诉我这里不正常的事情,如果需要,我很乐意提供更多信息