如何根据生命周期范围名称解决?

时间:2015-08-04 08:33:37

标签: c# autofac masstransit

我在同一个Windows服务中有一个包含多个逻辑服务(队列)的项目,我试图配置每个项目以拥有它自己的日志文件。所以我正在设置文件管理器的命名实例:

cb.RegisterType<LogFileHandler>()
  .Named<LogFileHandler>("Project1")
  .WithParameter("filename", "c:\\project1.txt")
  .SingleInstance();
cb.RegisterType<LogFileHandler>()
  .Named<LogFileHandler>("Project2")
  .WithParameter("filename", "c:\\project2.txt")
  .SingleInstance();

MassTransit集成为每个服务创建一个命名/标记范围,但似乎并不是在注册中获取此信息的方法。例如,如果我能做到这样的话会很棒:

cb.Register((x) => x.ResolveNamed<LogFileHandler>(x.Tag))
然而,x.Tag并不存在,那么有没有根据范围名称进行区分的方法?或者更好的方法呢?

1 个答案:

答案 0 :(得分:2)

您可以解析ILifetimeScope以获取有关注册方法的Tag信息。

builder.RegisterType<LogFileHandler>()
       .Named<LogFileHandler>("Project1")
       .WithParameter("filename", "c:\\project1.txt")
       .SingleInstance();
builder.RegisterType<LogFileHandler>()
       .Named<LogFileHandler>("Project2")
       .WithParameter("filename", "c:\\project2.txt")
       .SingleInstance();


builder.Register(c => {
            String tag = c.Resolve<ILifetimeScope>().Tag as String; 
            return c.ResolveNamed<LogFileHandler>(tag); 
       })
       .As<LogFileHandler>();

它应该有效,但是如果你有一个子范围或Owned依赖Tag在这个已解决的ILifetimeScope中不会出现。要解决此问题,您可以解析ISharingLifetimeScope并检查Parent属性。

builder.Register(c =>
{
    String tag;
    ISharingLifetimeScope scope = c.Resolve<ISharingLifetimeScope>();
    while (scope != null)
    {
        if (scope.Tag is String
            && new String[] { "Project1", "Project2" }.Contains((String)scope.Tag))
        {
            tag = (String)scope.Tag;
            break;
        }

        scope = scope.ParentLifetimeScope;
    }
    return c.ResolveNamed<LogFileHandler>(tag);
})
.As<LogFileHandler>();
只有当您直接从ISharingLifetimeScope解决问题而不是从子生命周期范围内解决问题时,

null才会解析为IContainer