为已自动激活的ComponentRegistration添加激活的事件

时间:2018-09-26 10:50:04

标签: c# .net-core autofac

我正在尝试将Activated事件处理程序附加到实现特定接口的Components上。

我想全局在一个地方执行此操作,而不必为每个注册调用一个方法。即OnActivated不适合,因为它是每个注册调用。

为此,我有一个RegisterBuildCallback,它会在适当的情况下循环附加到ComponentRegistry.Registrations事件的Activated

我发现的问题是运行Components之前已激活标记为AutoActivate的{​​{1}}。因此,RegisterBuildCallback不会被Activated AutoActivate调用,而是会在我附加事件处理程序之前被调用。

Components可以正常工作,并按照文档中的说明进行操作:

  

自动激活的组件是仅在容器生成后一次激活一次的组件

https://autofaccn.readthedocs.io/en/latest/lifetime/startup.html#auto-activated-components

这是MCVE:

AutoActivate

以下是输出:

    IBar Activated
    Found 2 ISomething Registrations
    ISomething Foo Add Activated
    ISomething Bar Add Activated
    ISomething Foo Activated

如上所述,我试图避免在注册using System; using System.Linq; using Autofac; namespace AutofacActivatedNotCalled { public interface ISomething { } public interface IFoo { } public interface IBar { } public class Foo : IFoo, ISomething { } public class Bar : IBar, ISomething { } public class Baz { public Baz(IFoo foo) { } } class Program { static void Main(string[] args) { var builder = new ContainerBuilder(); // Add callback which hooks up Activated event. builder .RegisterBuildCallback(builtContainer => { var iSomethingRegistrations = builtContainer .ComponentRegistry .Registrations .Where(registration => IsISomething(registration.Activator.LimitType)) .ToList(); Console.WriteLine($"Found {iSomethingRegistrations.Count} ISomething Registrations"); foreach (var iSomethingRegistration in iSomethingRegistrations) { Console.WriteLine($"ISomething {iSomethingRegistration.Activator.LimitType.Name} Add Activated"); iSomethingRegistration.Activated += (sender, eventArgs) => { Console.WriteLine($"ISomething {eventArgs.Instance.GetType().Name} Activated"); }; } }); // Register services builder.RegisterType<Foo>().As<IFoo>().SingleInstance(); builder .RegisterType<Bar>() .As<IBar>() .SingleInstance() .AutoActivate() .OnActivated(eventArgs => Console.WriteLine($"IBar Activated")); builder.RegisterType<Baz>(); // Build container var container = builder.Build(); // Resolve service var baz = container.Resolve<Baz>(); Console.ReadLine(); } private static bool IsISomething(Type type) => (type == typeof(ISomething)) || type.GetInterfaces().Any(interfaceType => interfaceType == typeof(ISomething)); } } 时使用OnActivated。该示例中包含的内容表明已触发Component,但在运行Activate之前。

有没有办法用我的方法来处理RegisterBuildCallback AutoActivated

1 个答案:

答案 0 :(得分:1)

AutoActivate在调用Build方法时被立即激活。您甚至不需要Activated事件来捕获它们。

将以下代码添加到RegisterBuildCallback-

var autoActivated = builtContainer
                                      .ComponentRegistry
                                      .Registrations
                                      .Where(registration => IsISomething(registration.Activator.LimitType) && registration.Services.Any(i => i.Description.Equals("AutoActivate")))
                                      .ToList();

                foreach (var iSomethingRegistration in autoActivated)
                {
                    Console.WriteLine($"Auto activated {string.Join("-", iSomethingRegistration.Services)} ");
                }