如何根据生命周期名称解析?

How to resolve based on lifetime scope name?

我有一个项目在同一个 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 集成为每个服务创建了一个 named/tagged 范围,但似乎没有办法在注册中获取此信息。例如,如果我能做这样的事情就好了:

cb.Register((x) => x.ResolveNamed<LogFileHandler>(x.Tag))
但是

x.Tag 不存在,那么有没有一种方法可以根据范围名称进行区分?或者总体上更好的方法?

你可以解析一个ILifetimeScope来获取Tag关于register方法的信息。

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 而不是从子生命周期范围解析某些东西时。