我有一個關於使用SimpleInjector或任何其他IoC框架的UoW模式的問題。應當指出的我已經閱讀了關於它的計算器不同的線程,更具體這兩個線程:Mixed lifestyle for Per Thread and Per Web Request with Simple Injector和How to configure Simple Injector to run background threads in ASP.NET MVC單元在WCF中使用Quartz(線程)
我正在開發一個WCF服務。該服務依賴於IUnitOfWork。我可以在SimpleInjector中註冊帶有RegsiterPerWcfOperation擴展的IUnitOfWork。然而,我的WCF服務還從Quartz調度器框架中衍生出一些新的作業(線程)。其中一個作業也包含對我的IUnitOfWork的依賴,因此我無法使用RegsiterPerWcfOperation。我可以做像計算器的一個線程說,和我的註冊IUnitOfWork這樣的:
ScopedLifestyle hybridLifestyle = Lifestyle.CreateHybrid(
() => OperationContext.Current != null || HttpContext.Current != null,
new WcfOperationLifestyle(),
new LifetimeScopeLifestyle());
container.Register<IUnitOfWork, UnitOfWork<TEntities>>(hybridLifestyle);
首先我不知道在OperationContext.Current
如果無效檢查是正確的,因爲我的WCF服務不運行在AspNetCompatibilityMode
,因爲NET.TCP綁定 - 所以HttpContext.Current
的空檢查不會幫助我,除非我運行我的WCF服務AspNetCompatibilityMode = true
?
好了,所以我的石英依賴已在容器中,我已經創建一個工廠,所以這個框架可以這樣創建我IJob
實例的實例:
public class SimpleInjectorJobFactory : IJobFactory
{
private static readonly ILog _log =
LogManager.GetLog(typeof(SimpleInjectorJobFactory));
private readonly Container _container;
public SimpleInjectorJobFactory(Container container) {
_container = container;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) {
IJobDetail jobDetail = bundle.JobDetail;
Type jobType = jobDetail.JobType;
try
{
if (_log.IsDebugEnabled) {
_log.Debug(string.Format("Producing Instance of job: {0}, class: {1}",
jobDetail.Key, jobType.FullName));
}
// Return job registrated in container
return (IJob)_container.GetInstance(jobType);
}
catch (Exception ex)
{
_log.Error("Problem instantiating class", ex);
throw new SchedulerException("Problem instantiating class", ex);
}
}
public void ReturnJob(IJob job) { }
}
的IJob外觀的實現像這樣:
public class MyJob : IJob
{
private static readonly ILog _log = LogManager.GetLog(typeof(MyJob));
private readonly IUnitOfWork _unitOfWork;
public MyJob(IUnitOfWork unitOfWork) {
_unitOfWork = unitOfWork;
}
public void Execute(IJobExecutionContext context) {
try
{
_unitOfWork.GetSomeDate().... //PSEUDO
}
catch (Exception ex)
{
_log.Error("Could not execute " + context.JobDetail.JobType, ex);
}
}
}
如果我應遵循從指定線程上面的建議,我會需要創建一個新的生命週期範圍,如:
try
{
using (container.BeginLifetimeScope())
{
var uow = container.GetInstance<IUnitOfWork>();
uow.GetSomeDate().... //PSEUDO
}
}
但是,使用這種解決方案,我不會與IoC框架緊密耦合嗎?我似乎無法找到解決此問題的適當方法。我讀了一些關於裝飾器的內容,但是我似乎無法弄清楚如何使用它們。我希望我能夠得到一個很好的例子,我該如何解決我的問題。
「container.GetCurrentWcfOperationScope()」和修飾符部分正是我所缺少的。很好的例子 - 感謝您的幫助! –