- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对使用 SimpleInjector 或任何其他 IoC 框架的 UoW 模式有疑问。应该注意的是,我已经在 stackoverflow 上阅读了有关它的各种线程,更具体地说,这两个线程: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 服务。该服务依赖于 IUnitOfWork。我可以在 SimpleInjector 中使用 RegsiterPerWcfOperation 扩展注册 IUnitOfWork。但是,我的 WCF 服务还从 Quartz 调度程序框架中生成了一些新作业(线程)。其中一项工作还包含对我的 IUnitOfWork 的依赖,因此我无法使用 RegsiterPerWcfOperation。我可以像其中一个 stackoverflow 线程所说的那样做,并像这样注册我的 IUnitOfWork:
ScopedLifestyle hybridLifestyle = Lifestyle.CreateHybrid(
() => OperationContext.Current != null || HttpContext.Current != null,
new WcfOperationLifestyle(),
new LifetimeScopeLifestyle());
container.Register<IUnitOfWork, UnitOfWork<TEntities>>(hybridLifestyle);
首先,我不确定 OperationContext.Current
的 null 检查是否正确,因为我的 WCF 服务没有在 AspNetCompatibilityMode
中运行,因为 NET .TCP 绑定(bind) - 所以对 HttpContext.Current
的空检查对我没有帮助,除非我使用 AspNetCompatibilityMode = true
运行我的 WCF 服务?
好的,所以我的 Quartz 依赖项已在容器中注册,并且我已经创建了一个工厂,因此框架可以像这样创建我的 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 框架紧密耦合吗?我似乎找不到合适的方法来解决这个问题。我已经阅读了一些关于装饰器的内容,但是我似乎无法弄清楚如何使用它们。我希望我能得到一个很好的例子,说明我如何解决我的问题。
最佳答案
你快到了。您需要创造以下混合生活方式:
var hybridLifestyle = Lifestyle.CreateHybrid(
container.GetCurrentWcfOperationScope() != null,
new WcfOperationLifestyle(),
new LifetimeScopeLifestyle());
您需要调用 container.GetCurrentWcfOperationScope()
或 container.GetCurrentLifetimeScope()
来确定选择哪种生活方式。
此外,您应该绝对避免在您的MyJob
(或任何作业实现)中引用Container
。那是 an anti-pattern .相反,您应该创建一个 IJob
装饰器,为作业添加生命周期范围行为:
// This class is part of your Composition Root
public class LifetimeScopeJobDecorator : IJob {
private readonly IJob _decoratee;
private readonly Container _container;
public LifetimeScopeJobDecorator(IJob decoratee, Container container) {
_decoratee = decoratee;
_container = container;
}
public void Execute(IJobExecutionContext context) {
using (_container.BeginLifetimeScope()) {
_decoratee.Execute(context);
}
}
}
现在有两种方法可以将装饰器应用于 SimpleInjectorJobFactory
返回的作业。最简单的方法是在 SimpleInjectorJobFactory.NewJob
方法中手动添加装饰器:
var job = (IJob)_container.GetInstance(jobType);
return new LifetimeScopeJobDecorator(job, _container);
让 Simple Injector 为您进行装饰会更漂亮,但在您的情况下这将是更多的代码。方法如下:
Type[] jobTypes = /* fetch IJob implementations here */;
// Instead of calling jobTypes.ToList().ForEach(container.Register), we register the
// types as a collection of IJob types.
container.RegisterAll<IJob>(types);
// Here we register the decorator
container.RegisterDecorator(typeof(IJob), typeof(LifetimeScopeJobDecorator));
// We create a jobFactory delegate.
// we use Lazy<T> because at this stage in the application the container might not
// be fully initialized yet.
var jobs = new Lazy<IEnumerable<IJob>>(() => container.GetAllInstance<IJob>());
var jobIndexes = types.ToDictionary(t => t, t => types.IndexOf(t));
Func<Type, IJob> jobFactory = jobType => jobs.Value.ElementAt(jobIndexes[jobType]);
// And pass that job factory on to the SimpleInjectorJobFactory.
var factory = new SimpleInjectorJobFactory(jobFactory);
// Inside the SimpleInjectorJobFactory:
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
// ...
// replace "return (IJob)_container.GetInstance(jobType);" with:
return _jobFactory(jobType);
// ...
}
最后一个解决方案更复杂,但是当您有多个装饰器时,这种方法会变得非常有趣,尤其是当它们需要根据实现类型有条件地应用时。这样工厂就不需要知道任何有关应用的装饰器的信息。
关于multithreading - WCF 中的 UnitOfWork 与 Quartz(线程),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21879646/
刚接触 Quartz,我对简单形状、渐变和阴影的绘制速度感到好奇;特别将 Quartz 绘图功能与 iPhone 上的 Quartz 图像绘制进行比较。 假设我需要绘制一个填充、描边和阴影的矩形。我假
我遇到了一个问题,即在包含要运行的类文件的应用程序之前部署 quartz-service.xml(使用 quartz 1.8.6 和 JBOSS 5.1.x)。有没有办法延迟 quartz 的启动?
我正在研究使用Quartz Scheduler,并且想知道是否可以按时间而不是按时间调度作业,而可以在另一个作业完成时进行调度。因此,当作业A完成时,它将启 Action 业B。完成后,它将启 Act
我正在使用 Quartz 进行一个项目,并且一直存在与作业的依赖关系的问题。 我们有一个设置,其中 A 和 B 不相互依赖,但 C 是: A 和 B 可以同时运行,但 C 只能在 A 和 B 都完成的
JobDetail.requestsRecovery 的文档属性(property)声明如下 Instructs the Scheduler whether or not the Job should
我得到的调度程序如下: StdScheduler schedulerBean = (StdScheduler) ApplicationContextUtil.getBean(schedulerBean
我正在使用 CronTriggerBean 和 SimpleTriggerBean quartz 调度程序来执行触发器。执行触发器后永久不保存有关触发器的详细信息。在执行之前触发器数据被存储在执行之后
我在我的 .NETCore 服务器中使用 Serilog,并在我的云部署中使用多个接收器,例如控制台、文件和 Graylog (GELF)。 一旦我将日志级别设置为 DEBUG,我每隔几秒钟就会从 q
全部, 我们配置了一个 Quartz.net 调度器。其配置如下: 在分析数据库时,我们注意到以下流量每 23-27 秒执行一次: exec sp_executesql N'SELECT
目前我有一个代码,它有一个 java main 方法,它的执行需要很少的命令行参数。我正在将此作为 quartz 作业,我想将参数传递给这项工作。 有什么办法可以做到吗?我对 JobDataMap 进
我正在使用 Quartz Scheduler,有 15 个工作。对于每项工作,都有一个触发器。 我想为每个触发器设置优先级。我可以将低优先级设置为 10,将高优先级设置为 1。 但是因为我有 15 个
我正在使用 Quartz 框架,对时间生成有点困惑。这是一个简单的代码,它在上午 11:30 生成每日触发器。为了测试这一点,我使用 ComputeFireTimes 查询生成了接下来的 100 个连
我正在使用 Quartz 调度,更具体地说是一个设置为每周每天晚上 10 点醒来的 cron 触发器。 我接触的另一个小组正在询问调度程序在一天中将唤醒多少次以检查它是否需要运行作业。晚上 10 点作
我们有一个托管在 IIS 8.0 上的 Intranet 应用程序。 我们有一些可用的网络方法需要在特定时间执行。 因此,我们使用了 Quartz 调度程序来调度执行 Web 方法的作业。在 glob
我有一个 quartz 作业,每天下午 3 点(服务器时间)运行。我想做的是让它在下午 3 点运行,但针对美国的每个时区。 quartz 作业会触发一封电子邮件给我的用户,我希望每个人都能在他们的时间
我正在尝试在我的 web 项目中使用 Quartz.net。我这样配置我的应用程序: CRMMoreThanOneJob jobGroup1 ReportingPortalBLL.Job
我们有 2 个应用程序使用 quartz 进行调度。我们应用程序的 quartz.properties 如下: org.quartz.scheduler.instanceName = sr22Quar
我有一些关于 Quartz 集群的问题,特别是关于触发器如何在集群内执行。 在执行作业时,quartz 是否对节点有任何偏好?例如总是或从不上次执行相同作业的节点,或者只是哪个节点首先执行作业? 是否
我记得我们不能终止当前正在运行的 Quartz Job,但我们可以中断并在必要时进行 bool 检查,是否需要进一步进行后续操作。 即使我们实现 InterruptableJob并调用schedule
我已经执行了 2 个作业( MyJob1 和 MyJob2 ),如下所示: public async Task ScheduleJob() { await _jobManage
我是一名优秀的程序员,十分优秀!