我正在尝试将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
?
答案 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)} ");
}