使用Autofac IoC单例共享接口的Hangfire作业

时间:2017-01-09 20:18:27

标签: asp.net model-view-controller singleton autofac hangfire

我似乎无法找到有关此事的任何信息,希望有人可以提供帮助。

使用课程" TestClass"继承ITestClass我可以使用以下代码注册一个Autofac单例:

builder.RegisterType<TestClass>().As<ITestClass>().SingleInstance();

向Hangfire添加工作同样简单:

RecurringJob.AddOrUpdate<ITestClass>(x => x.MethodInITestClass, Cron.MinuteInterval(1));

我似乎无法弄清楚如何将多个类注册为Autofac单例,它们都具有相同的接口,并且能够为特定的单例创建一个Hangfire作业。

例如,有一个名为ITest的接口和使用此接口的类TestClass1,TestClass2和TestClass3,我想为TestClass2添加一个Hangfire作业。

我认为也许名为单身人士的解决方案可以轻松创建:

builder.RegisterType<TestClass1>().Named<ITest>("TestClass1").SingleInstance();
builder.RegisterType<TestClass2>().Named<ITest>("TestClass2").SingleInstance();
builder.RegisterType<TestClass3>().Named<ITest>("TestClass3").SingleInstance();

但是,为TestClass2添加一个Hangfire作业似乎是不可能的,因为Hangfire只接受一个接口作为参数,而接口现在有3个相关的单例。

我还希望能够将实现此接口的所有单例解析为IEnumerable,这对于命名单例来说似乎是不可能的。

对此有何建议?我想名叫单身人士可能是一个死胡同?

2 个答案:

答案 0 :(得分:0)

我不认为命名或键控服务会对您有所帮助。我查看了JobActivator实现,似乎没有办法在解析服务的ActivateJob(Type jobType)方法中提供名称或密钥。

  

但是,为TestClass2添加一个Hangfire作业似乎是不可能的,因为Hangfire只接受一个接口作为参数,接口现在有3个相关的单例。

我认为这不正确,因此您可以在添加作业时直接使用单例类型(TestClass1TestClass2,...)。要做到这一点,你还必须注册你的单身人士AsSelf()

builder.RegisterType<TestClass>().AsSelf().As<ITestClass>().SingleInstance();

您仍然可以使用ITestClass界面解决所有单身人士问题。如果您无法在添加作业的代码中访问单件类型,则必须为每个单例添加一个界面(ITestClass1ITestClass2,...)然后使用这些界面来创建作业。

答案 1 :(得分:0)

感谢您的回答fknx! :)

我看到这样注册:

# data 
raw_df <- data.frame(id = 1:2, json = c('{"user": "xyz2", "weightmap": {"P1":100,"P2":0}, "domains": ["a2","b2"]}', '{"user": "xyz1", "weightmap": {"P1":0,"P2":100}, "domains": ["a1","b1"]}'), stringsAsFactors = FALSE)

# libraries
library(jsonlite)
library(data.table)


# 1) First, make a transformation function that works for a single entry
f <- function(json, id){
  # transform json to list
  tmp    <- jsonlite::fromJSON(json)

  # transform list to data.frame
  tmp    <- as.data.frame(tmp)

  # add id
  tmp$id <- id

  # return
  return(tmp)
}


# 2) apply it via mapply 
json_dfs <- 
  mapply(f, raw_df$json, raw_df$id, SIMPLIFY = FALSE)


# 3) combine the fragments via rbindlist
clean_df <- 
  data.table::rbindlist(json_dfs)

# 4) et-voila
clean_df
##    user weightmap.P1 weightmap.P2 domains id
## 1: xyz2          100            0      a2  1
## 2: xyz2          100            0      b2  1
## 3: xyz1            0          100      a1  2
## 4: xyz1            0          100      b1  2

..将使我能够使用ITestClass解决所有问题。我不知道如何能够为TestClass2注册Hangfirejob?

如果我无法访问单件类型,那么您提出的解决方案工作效果很好!

注册:

builder.RegisterType<TestClass1>().AsSelf().As<ITestClass>().SingleInstance();

builder.RegisterType<TestClass2>().AsSelf().As<ITestClass>().SingleInstance();

builder.RegisterType<TestClass3>().AsSelf().As<ITestClass>().SingleInstance();

另外,我让ITestClassX继承ITestClass,这样如果我通过ITestClassX或ITestClass解析,我仍然可以访问相同的方法。

添加Hangfire作业:

builder.RegisterType<TestClass1>().As<ITestClass1>().As<ITestClass>().SingleInstance();

builder.RegisterType<TestClass2>().As<ITestClass2>().As<ITestClass>().SingleInstance();

builder.RegisterType<TestClass3>().As<ITestClass3>().As<ITestClass>().SingleInstance();